private void RunAsync()
{
string param = "Hi";
Task.Run(() => MethodWithParameter(param));
}
private void MethodWithParameter(string param)
{
}
Bearbeiten
Aufgrund der großen Nachfrage muss ich beachten, dass der TaskStart parallel zum aufrufenden Thread ausgeführt wird. Unter der Annahme der Standardeinstellung TaskSchedulerwird .NET verwendet ThreadPool. Auf jeden Fall bedeutet dies, dass Sie berücksichtigen müssen, welche Parameter an die Taskpotenziell als von mehreren Threads gleichzeitig zugegriffen werden, sodass sie gemeinsam genutzt werden. Dies beinhaltet den Zugriff auf sie im aufrufenden Thread.
In meinem obigen Code ist dieser Fall völlig umstritten. Saiten sind unveränderlich. Deshalb habe ich sie als Beispiel genommen. Aber sagen Sie, Sie verwenden keine String...
Eine Lösung ist die Verwendung von asyncund await. Dies erfasst standardmäßig SynchronizationContextden aufrufenden Thread und erstellt nach dem Aufruf eine Fortsetzung für den Rest der Methode awaitund hängt sie an den erstellten an Task. Wenn diese Methode auf dem WinForms-GUI-Thread ausgeführt wird, ist sie vom Typ WindowsFormsSynchronizationContext.
Die Fortsetzung wird ausgeführt, nachdem sie wieder in den erfassten Bereich gebucht wurde SynchronizationContext- wiederum nur standardmäßig. Sie befinden sich also wieder in dem Thread, mit dem Sie nach dem awaitAufruf begonnen haben. Sie können dies auf verschiedene Arten ändern, insbesondere mit ConfigureAwait. Kurz gesagt, der Rest dieser Methode wird erst fortgesetzt, nachdem der TaskVorgang in einem anderen Thread abgeschlossen wurde. Der aufrufende Thread wird jedoch weiterhin parallel ausgeführt, nur nicht der Rest der Methode.
Dieses Warten auf den Abschluss des Restes der Methode kann wünschenswert sein oder auch nicht. Wenn nichts in dieser Methode später auf die Parameter zugreift, die an übergeben wurden, Taskmöchten Sie sie möglicherweise überhaupt nicht verwenden await.
Oder vielleicht verwenden Sie diese Parameter viel später in der Methode. Kein Grund, awaitsofort, da Sie sicher weiterarbeiten können. Denken Sie daran, dass Sie die zurückgegebenen TaskDaten in einer Variablen und awaitspäter darauf speichern können - auch mit derselben Methode. Zum Beispiel, wenn Sie nach einer Reihe anderer Arbeiten sicher auf die übergebenen Parameter zugreifen müssen. Auch hier haben Sie nicht brauchen , um awaitauf dem TaskRecht , wenn Sie es starten.
Eine einfache Möglichkeit, diesen Thread in Bezug auf die übergebenen Parameter sicher zu machen, Task.Runbesteht darin, Folgendes zu tun:
Sie müssen zuerst dekorieren RunAsyncmit async:
private async void RunAsync()
Wichtige Notiz
Vorzugsweise sollte die markierte Methode nicht ungültig sein, wie in der verknüpften Dokumentation erwähnt. Die häufigste Ausnahme sind Ereignishandler wie Schaltflächenklicks und dergleichen. Sie müssen ungültig zurückkehren. Ansonsten versuche ich immer ein oder bei Verwendung zurückzugeben . Es ist aus mehreren Gründen eine gute Übung.async TaskTask<TResult>async
Jetzt können Sie awaitdas TaskFolgende unten ausführen. Sie können nicht awaitohne verwenden async.
await Task.Run(() => MethodWithParameter(param));
Wenn Sie also awaitdie Aufgabe übernehmen, können Sie im Allgemeinen vermeiden, übergebene Parameter als potenziell gemeinsam genutzte Ressource zu behandeln, mit all den Gefahren, etwas aus mehreren Threads gleichzeitig zu ändern. Achten Sie auch auf Verschlüsse . Ich werde nicht näher darauf eingehen, aber der verlinkte Artikel leistet hervorragende Arbeit.
Randnotiz
Ein bisschen abseits des Themas, aber seien Sie vorsichtig, wenn Sie den WinForms-GUI-Thread mit "Blockieren" versehen, da er mit markiert ist [STAThread]. Die Verwendung awaitwird überhaupt nicht blockiert, aber ich sehe manchmal, dass sie in Verbindung mit einer Art Blockierung verwendet wird.
"Blockieren" steht in Anführungszeichen, da Sie den WinForms-GUI-Thread technisch nicht blockieren können . Ja, wenn Sie lockden WinForms-GUI-Thread verwenden, werden weiterhin Nachrichten gepumpt, obwohl Sie denken, dass er "blockiert" ist. Es ist nicht.
Dies kann in sehr seltenen Fällen bizarre Probleme verursachen. Einer der Gründe, warum Sie lockzum Beispiel beim Malen niemals einen verwenden möchten . Aber das ist ein Randfall und ein komplexer Fall. Ich habe jedoch gesehen, dass es verrückte Probleme verursacht. Der Vollständigkeit halber habe ich es notiert.