Wie erstelle ich eine Aufgabe (TPL), auf der ein STA-Thread ausgeführt wird?

75

Die Verwendung von Thread ist ziemlich einfach

 Thread thread = new Thread(MethodWhichRequiresSTA);
 thread.SetApartmentState(ApartmentState.STA);  

Wie kann ich dasselbe mit Aufgaben in einer WPF-Anwendung erreichen? Hier ist ein Code:

Task.Factory.StartNew
  (
    () => 
    {return "some Text";}
  )
   .ContinueWith(r => AddControlsToGrid(r.Result));  

Ich erhalte eine InvalidOperationException mit

Der aufrufende Thread muss STA sein, da dies für viele UI-Komponenten erforderlich ist.

Michel Triana
quelle

Antworten:

75

Mit der TaskScheduler.FromCurrentSynchronizationContext-Methode können Sie einen TaskScheduler für den aktuellen Synchronisationskontext abrufen (dies ist der WPF-Dispatcher, wenn Sie eine WPF-Anwendung ausführen ).

Verwenden Sie dann die ContinueWith- Überladung, die einen TaskScheduler akzeptiert:

var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(...)
            .ContinueWith(r => AddControlsToGrid(r.Result), scheduler);
dtb
quelle
10
Nur um es klar auszudrücken; Nur das Lambda in der ContinueWith-Methode wird mit dem richtigen Kontext ausgeführt, nicht das, was in der Hauptaufgabe Lambda ausgeführt wird.
dudeNumber4
Vielen Dank dafür, ich habe versucht TaskScheduler.Current(aus einem WinForms Button Event Handler), konnte nicht verstehen, warum es nicht funktioniert ...
Benjol
11
Zur Verdeutlichung gibt es auch eine Überladung für die Instanzmethode Task.Start (), die einen TaskScheduler verwendet. Die Details der Frage machen deutlich, dass wir uns mehr für den Fortsetzungsfall interessieren, aber die allgemeinere Frage, wie eine Aufgabe in einem STA-Thread ausgeführt wird, ist nicht nur auf diesen Fall beschränkt. Ich habe zunächst fälschlicherweise angenommen, dass ich von einer leeren "Fudge" -Aufgabe fortfahren muss, um meine gewünschte STA-Aufgabe auszuführen.
Josh Sutterfield
2
Sollte der Titel dieser Frage nicht bearbeitet werden, um ihre Absicht besser widerzuspiegeln?
Mrchief
Oder in zwei Teile zerlegt. "Wie starte ich eine Aufgabe in einem STA-Thread?" Und "Wie setze ich eine Aufgabe in einem STA-Thread fort?".
David