Tôi đã xem qua một số phương pháp hay nhất để lập trình không đồng bộ bằng cách sử dụng c #'s async
/ await
keywords (tôi mới sử dụng c # 5.0).
Một trong những lời khuyên được đưa ra là:
Tính ổn định: Biết bối cảnh đồng bộ hóa của bạn
... Một số ngữ cảnh đồng bộ hóa là không thể nhập lại và đơn luồng. Điều này có nghĩa là chỉ một đơn vị công việc có thể được thực thi trong ngữ cảnh tại một thời điểm nhất định. Ví dụ về điều này là chuỗi giao diện người dùng Windows hoặc ngữ cảnh yêu cầu ASP.NET. Trong các bối cảnh đồng bộ hóa đơn luồng này, bạn rất dễ tự bế tắc. Nếu bạn sinh ra một nhiệm vụ từ ngữ cảnh đơn luồng, sau đó đợi tác vụ đó trong ngữ cảnh, mã chờ của bạn có thể đang chặn tác vụ nền.
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
Nếu tôi cố gắng tự mình mổ xẻ nó, luồng chính sẽ sinh ra một luồng mới MyWebService.GetDataAsync();
, nhưng vì luồng chính đang đợi ở đó, nó sẽ đợi kết quả trong GetDataAsync().Result
. Trong khi đó, nói rằng dữ liệu đã sẵn sàng. Tại sao chuỗi chính không tiếp tục nó là logic tiếp tục và trả về kết quả chuỗi từ đó GetDataAsync()
?
Ai đó có thể vui lòng giải thích cho tôi tại sao có một bế tắc trong ví dụ trên không? Tôi hoàn toàn không biết vấn đề là gì ...