Основываясь на многочисленных книгах и блогах, включая this excellent one here, ясно, что при записи библиотеки dll, выставляющей вспомогательные асинхронные методы, то есть методы обертки, обычно считается лучшей практикой для внутреннего завершения ввода/вывода задачу фактических асинхронных методов на Threadpool нити так, как (псевдо-код показан ниже для краткости, и я использую HttpClient
в качестве примера)C# async/await chaining with ConfigureAwait (false)
public Async Task<HttpResponseMessage> MyMethodAsync(..)
{
...
var httpClient = new HttpClient(..);
var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false);
...
return response;
}
ключевым моментом здесь является использование ConfigureAwait(false)
таким образом, что Выполнение задачи ввода-вывода происходит в потоке threadpool вместо исходного контекста потока, что потенциально предотвращает взаимоблокировки.
Мой вопрос с точки зрения вызывающего. Меня особенно интересует сценарий, в котором есть уровни вызовов методов между вызывающим и вышеупомянутым вызовом метода, как показано в следующем примере.
CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync
Является ли это достаточно, чтобы иметь ConfigureAwait(false)
на конечном методе или только должен также обеспечить один Method1Async
и Method2Async
также внутренне называют свои методы асинхронных с ConfigureAwait(false)
? Кажется глупым включать все эти промежуточные методы, особенно если Method1Async
и Method2Async
являются просто перегрузками, которые в конечном итоге вызывают MyMethodAsync
. Любые мысли, пожалуйста, просветите нас!
Обновлено в примере Так что, если у меня есть библиотека со следующим частным методом асинхронной,
private async Task<string> MyPrivateMethodAsync(MyClass myClass)
{
...
return await SomeObject.ReadAsStringAsync().ConfigureAwait(false);
}
Я должен убедиться, что следующие публичные перегруженные методы и также включают ConfigureAwait (ложь), как показано ниже?
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);
}
При использовании 'ConfigureAwait (false)' является хорошей практикой для кода библиотеки, его использование может иметь свои собственные последствия: http://stackoverflow.com/q/28410046 – Noseratio