Sulla base di numerosi libri e blog tra cui this excellent one here, è chiaro che quando si scrive una libreria dll che espone metodi asincroni helper cioè i metodi wrapper, è generalmente considerata una best practice per internamente completare l'operazione di I/O di metodi asincrone attuali su un filo di thread in questo modo (pseudo codice riportato di seguito per brevità e sto usando HttpClient
come esempio)C# asincrono/attendi concatenamento con ConfigureAwait (falso)
public Async Task<HttpResponseMessage> MyMethodAsync(..)
{
...
var httpClient = new HttpClient(..);
var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false);
...
return response;
}
la chiave qui è l'utilizzo di ConfigureAwait(false)
affinché Il completamento delle attività di I/O si verifica su un thread del threadpool anziché sul contesto del thread originale, evitando potenzialmente i deadlock.
La mia domanda è dal punto di vista di un chiamante. Sono particolarmente interessato a uno scenario in cui vi siano livelli di chiamate di metodo tra il chiamante e la chiamata al metodo precedente, come illustrato nel seguente esempio.
CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync
E 'sufficiente avere ConfigureAwait(false)
sul metodo finale unica o si dovrebbe inoltre garantire Method1Async
e Method2Async
anche internamente chiamare i loro metodi asincroni con ConfigureAwait(false)
? Sembra strano averlo incluso in tutti questi metodi di intermediazione, specialmente se Method1Async
e Method2Async
sono semplicemente sovraccarichi che finiscono per chiamare MyMethodAsync
. Qualche idea, per favore ci illumini!
Aggiornato con Esempio Quindi, se ho una libreria con il seguente metodo asincrono privato,
private async Task<string> MyPrivateMethodAsync(MyClass myClass)
{
...
return await SomeObject.ReadAsStringAsync().ConfigureAwait(false);
}
devo assicurarsi che i seguenti metodi di overload pubblici sia includono anche ConfigureAwait (false) come mostrato di seguito?
public async Task<string> MyMethodAsync(string from)
{
return await MyPrivateMethodAsync(new (MyClass() { From = from, To = "someDefaultValue"}).ConfigureAwait(false);
}
public async Task<string> MyMethodAsync(string from, string to)
{
return await MyPrivateMethodAsync(new (MyClass() { From = from, To = to }).ConfigureAwait(false);
}
Durante l'utilizzo di 'ConfigureAwait (false)' è una buona pratica per un codice libreria, il suo utilizzo potrebbe avere le sue implicazioni: http://stackoverflow.com/q/28410046 – Noseratio