2013-09-03 29 views
5

Đây là một chút hơi dài, nhưng ở đây đi ....Làm thế nào để chờ đợi trên Task.Result ảnh hưởng đến các phương thức async/await lồng nhau?

Cho rằng tôi có một giao diện như sau:

public interface IWebClientHelper 
{ 
    TPayload Get<TPayload>(string url); 
} 

Trường hợp thực hiện Get thực hiện cuộc gọi đến URL được cung cấp, trong đó sẽ trả về một đáp ứng có chứa một đối tượng Json loại TPayload), và rằng Json được deserialized thành TPayload và sau đó quay trở lại.

Tôi muốn làm cho việc thực hiện các phương pháp không đồng bộ Get (hay cụ thể hơn thực hiện cuộc gọi HTTP chứa trong Get phương pháp không đồng bộ), nhưng như tôi hiểu nó, đó sẽ đòi hỏi rằng chữ ký của phương pháp Get được thay đổi để:

Task<TPayload> Get<TPayload>(string url); 

tôi nhằm giữ cho giao diện như nó có, vì vậy tôi đã tạo ra một giao diện thứ hai:

public interface IAsyncWebClientHelper 
{ 
    Task<TPayload> Get<TPayload>(string url); 
} 

và tiêm đó vào implem của tôi sự lôi kéo của IWebClientHelper. Vì vậy bây giờ thực hiện của tôi IWebClientHelper trông như thế này:

public TPayload Get<TPayload>(string url) 
{ 
    return _asyncWebClientHelper.Get<TPayload>(url).Result; 
} 

và phương pháp Get của _asyncWebClientHelper chứa dòng

message = await httpClient.GetAsync(url); 

Vì vậy, những gì tôi không rõ ràng về vấn đề này là: Tôi thích hợp trong suy nghĩ rằng dòng return _asyncWebClientHelper.Get<TPayload>(url).Result sẽ chặn thực thi cho đến khi phương thức đó trả về? Hay từ khóa await bên trong phương thức đó sẽ giải phóng chuỗi cho đến khi nó nhận được phản hồi từ url?

+2

Đó là tính năng đồng bộ hóa quá mức không đồng bộ. – usr

Trả lời

19

Có, sử dụng Result có nghĩa là phương pháp của bạn sẽ chặn. Tuy nhiên, nó hoàn toàn có thể có nghĩa là nó sẽ thực sự gây ra bế tắc. Bạn đã không nói với chúng tôi nhiều về bối cảnh, nhưng nếu bạn đang ở trong một bối cảnh mà sau khi các await bạn cần phải quay trở lại cùng một chủ đề, nhưng thread đó bị chặn do Result, bạn về cơ bản bế tắc trên chính mình . Bạn cần phải cẩn thận rất nơi bạn sử dụng bất kỳ cuộc gọi chặn nào như thuộc tính Result hoặc phương pháp Wait().

Về cơ bản, cố gắng sử dụng không đồng bộ mà không làm cho giao diện của bạn không đồng bộ là khó khăn/vô nghĩa. Bạn muốn được tốt hơn nhiều ôm lấy không đồng bộ toàn bộ, hoặc gắn bó với các phiên bản đồng bộ. Sau khi tất cả, nếu bạn đang đi để giữ một thread bị chặn cho đến khi nhiệm vụ không đồng bộ đã hoàn thành, lợi ích của asynchrony ở nơi đầu tiên là gì?

+0

Tôi nghĩ rằng đây có thể là trường hợp, chỉ muốn chắc chắn trước khi tôi thiết lập về thay thế tất cả 64 tham chiếu đến giao diện đồng bộ ... –

+1

@ paynecrl97: Bạn có sự thông cảm của tôi. Chuyển đổi mã từ đồng bộ hóa sang async không bao giờ là thú vị. –

Các vấn đề liên quan