Dựa trên nhiều sách và blog bao gồm this excellent one here, rõ ràng là khi viết một thư viện dll để hiển thị các phương thức async trợ giúp tức là các phương thức bao bọc, thường được coi là phương pháp hay nhất để nội bộ hoàn thành nhiệm vụ I/O của phương pháp async thực tế trên một sợi threadpool như vậy (pseudo code hiển thị dưới đây cho ngắn gọn và tôi đang sử dụng HttpClient
là một ví dụ)C# async/await chaining với ConfigureAwait (false)
public Async Task<HttpResponseMessage> MyMethodAsync(..)
{
...
var httpClient = new HttpClient(..);
var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false);
...
return response;
}
Mấu chốt ở đây là việc sử dụng ConfigureAwait(false)
để Hoàn thành nhiệm vụ IO xảy ra trên một thread threadpool thay vì trên bối cảnh thread ban đầu, do đó có khả năng ngăn ngừa deadlocks.
Câu hỏi của tôi là từ góc nhìn của người gọi. Tôi đặc biệt quan tâm đến một kịch bản có các lớp gọi phương thức giữa người gọi và cuộc gọi phương thức trên, như ví dụ sau đây.
CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync
Có đủ để có ConfigureAwait(false)
vào phương pháp cuối cùng chỉ hay nên người ta cũng đảm bảo Method1Async
và Method2Async
cũng trong nội bộ gọi các phương thức async của họ với ConfigureAwait(false)
? Có vẻ ngớ ngẩn khi đưa nó vào tất cả các phương pháp trung gian này, đặc biệt nếu Method1Async
và Method2Async
chỉ đơn giản là quá tải mà kết thúc gọi MyMethodAsync
. Bất kỳ suy nghĩ nào, hãy khai sáng cho chúng tôi!
cập nhật với Ví dụ Vì vậy, nếu tôi có một thư viện với các phương pháp async tin sau đây,
private async Task<string> MyPrivateMethodAsync(MyClass myClass)
{
...
return await SomeObject.ReadAsStringAsync().ConfigureAwait(false);
}
tôi nên chắc chắn các phương pháp quá tải công cộng sau cả hai cũng bao gồm ConfigureAwait (sai) như hình dưới đây?
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);
}
Trong khi sử dụng 'ConfigureAwait (false)' là một thực hành tốt cho mã thư viện, việc sử dụng nó có thể có ý nghĩa riêng của nó: http://stackoverflow.com/q/28410046 – Noseratio