2015-09-03 18 views
8

Secondo le migliori pratiche si consiglia di utilizzare .ConfigureAwait(false) con async/await parole chiave, se potete:Quando non riesco a utilizzare ConfigureAwait (false)?

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

Potete per favore mi dia un esempio di una situazione in cui non posso usare .ConfigureAwait(false)? .

+3

È quando è necessario che la continuazione ritorni nel contesto da cui è originata, quindi la maggior parte canonica del contesto dell'interfaccia utente. –

+0

@AdamHouldsworth giusto, ora ha perfettamente senso per me – Andrei

risposta

11

È "non può" uso ConfigureAwait(false) quando effettivamente preoccupate per il contesto di sincronizzazione ci si trova per esempio, immaginate quanto segue in un'applicazione GUI:

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

quando si torna da ConfigureAwait, è non tornerai sul thread dell'interfaccia utente. Ciò causerà un InvalidOperationException.

1

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

Quando si aspetti la su un metodo con attendono parola chiave, il compilatore genera mucchio di codice in nome di voi. Uno degli scopi di questa azione consiste nel gestire la sincronizzazione con il thread UI (o principale). Il componente chiave di questa funzione è il SynchronizationContext.Current che ottiene il contesto di sincronizzazione per il thread corrente. SynchronizationContext.Current viene popolato in base all'ambiente in cui ci si trova. Il metodo GetAwaiter di Attività cerca SynchronizationContext.Current. Se il contesto di sincronizzazione corrente è non null, la continuazione che viene passata a tale utente riceverà postata in quel contesto di sincronizzazione.

Quando si consumano un metodo, che utilizza il nuovo linguaggio asincrono caratteristiche, in modo di blocco, si finirà con una situazione di stallo, se si dispone di un SynchronizationContext disponibili. Quando si consumano i metodi in blocco (in attesa del metodo Task with Wait o si acquisisce il risultato direttamente dalla proprietà Result del task ), si bloccherà il thread principale allo stesso tempo. Quando alla fine l'attività si completa all'interno di tale metodo nel threadpool, è che invoca la continuazione per postare nuovamente il thread principale perché SynchronizationContext.Current è disponibile e acquisito. Ma c'è un problema qui: il thread dell'interfaccia utente è bloccato e hai un deadlock !

Problemi correlati