2015-09-03 3 views
8

Nach Best Practices wird empfohlen .ConfigureAwait(false) mit async/await Keywords verwenden, wenn Sie können:Wann kann ich ConfigureAwait (false) nicht verwenden?

await Task.Run(RunSomethingAsync).ConfigureAwait(false); 

Können Sie bitte geben Sie mir ein Beispiel für eine Situation, wenn ich nicht .ConfigureAwait(false) verwenden kann? .

+3

Es ist, wenn Sie die Fortsetzung benötigen, um den Kontext zurückzugeben, aus dem es stammt, so kanonisch der UI-Kontext. –

+0

@AdamHouldsworth richtig, jetzt macht es für mich vollkommen Sinn – Andrei

Antwort

11

Sie „kann nicht“ Verwendung ConfigureAwait(false), wenn Sie kümmern tatsächlich über den Synchronisationskontext Sie in sind zum Beispiel vor, das folgende in einer GUI-Anwendung:

public async void SomeButtonClick(object sender, EventArgs e) 
{ 
    var result = await SomeAsyncOperation().ConfigureAwait(false); 
    textBox.Text = result; 
} 

Wenn Sie von ConfigureAwait zurückkehren, Sie werde nicht wieder auf dem UIhread sein. Dies wird eine InvalidOperationException verursachen.

1

Vom source: Asynchronous .NET Client Libraries for Your HTTP API and Awareness of async/await's Bad Effects:

Wenn Sie auf eine Methode mit await Stichwort warten, Compiler erzeugt Reihe von Code im Namen von euch. Einer der Zwecke dieser Aktion ist die Synchronisierung mit dem UI-Thread (oder dem Hauptthread). Der Schlüssel Komponente dieser Funktion ist die SynchronizationContext.Current, die den Synchronisierungskontext für den aktuellen Thread erhält. SynchronizationContext.Current ist abhängig von der Umgebung, in der Sie sich befinden. Die GetAwaiter Methode der Aufgabe sucht nach SynchronizationContext.Current. Wenn der aktuelle Synchronisationskontext nicht null ist, wird die Fortsetzung, die an diesen Erwarter übergeben wird, an diesen Synchronisationskontext zurückgegeben.

Wenn Sie eine Methode verwenden, die die neue asynchrone Sprache Features in einer blockierenden Weise verwendet, werden Sie mit einem Deadlock enden, wenn Sie einen verfügbaren SynchronizationContext haben. Wenn Sie solche Methoden blockieren (warten auf die Task mit Wait Methode oder das Ergebnis direkt aus der Ergebniseigenschaft der Aufgabe nehmen), werden Sie den Haupt-Thread zur gleichen Zeit blockieren. Wenn schließlich die Task innerhalb dieser Methode im Threadpool abschließt, ruft sie auf, um die Fortsetzung an den Hauptthread zu senden, da SynchronizationContext.Current verfügbar und erfasst ist. Aber gibt es ein Problem hier: Der UI-Thread ist blockiert und Sie haben eine Deadlock!

Verwandte Themen