2014-12-04 6 views
5

Gewährleistet ConfigureAwait(false), dass Continuation auf einem anderen Thread ausgeführt wird oder nur signalisiert, dass es nicht zwingend erforderlich ist, auf demselben Thread zu laufen?Wie kann sichergestellt werden, dass die asynchrone Methodenfortsetzung in einem anderen Thread ausgeführt wird?

Gibt es eine Möglichkeit, diese Garantie zu gewährleisten?

Ich muss Kontextfluss über Threads testen.

+3

Die Aufgabe kann auch synchron auf dem gleichen Thread abgeschlossen werden, in diesem Fall "ConfigureAwait (false)" tut einfach nichts. IMO, der einfachste Weg, um die Garantie, die Sie suchen, ist die Verwendung eines benutzerdefinierten Warter (anstelle von 'ConfiguredTaskAwaitable'). – Noseratio

+1

@Noseratio Danke für diesen Kommentar. Ich habe diese Möglichkeit völlig vergessen. –

+0

Kein Problem; Insgesamt würde ich nicht zählen Count 'ConfigureAwait (false)' zu etwas mehr als eine Optimierung, um redundante Kontextwechsel zu vermeiden. Beachten Sie, was [MSDN-Dokumente sagen] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.configureawait%28v=vs.110%29.aspx): * true zu versuchen Marshal die Fortsetzung zurück zum ursprünglichen Kontext erfasst; Andernfalls ist false. * Alle anderen Verhaltensweisen, die über diese Anweisung hinausgehen, sind nicht dokumentiert und können versionsspezifisch sein. – Noseratio

Antwort

8

Mit ConfigureAwait(false) wird der Warner angewiesen, den erfassten Kontext nicht fortzusetzen, und daher wird SynchronizationContext ignoriert. Das bedeutet, dass die Fortsetzung nach dem Standard TaskScheduler geplant wird, der ThreadPool Threads verwendet.

Wenn der ursprüngliche Thread ein ThreadPool Thread war, kann die Fortsetzung auf dem gleichen Thread ausgeführt werden, andernfalls wird garantiert, dass es ein anderer Thread ist.

Sie können den Test mit einem dedizierten Thread ohne SynchronizationContext (oder mit ConfigureAwait(false)) starten, um sicherzustellen, dass sich die Threads vor und nach der Operation async unterscheiden.

0

Es gibt unten Szenario, das ConfigureAwait(false) keinen neuen Kontext ausführt.

Task task2Seconds = Wait2Seconds(); 
Task task5Seconds = Wait5Seconds(); 

await task5Seconds; 
await task2Seconds.ConfigureAwait(false); 

Die ersten await haben nicht, dass ConfigureAwait(false) aber es dauert länger als die zweiten await, der diesen configure hat aber bereit sein, im Voraus fortzusetzen. Also wird die zweite im selben Kontext fortgesetzt.

Verwandte Themen