2012-03-03 43 views
5

Tôi có phương thức thực hiện cuộc gọi không đồng bộ với dịch vụ web. Một cái gì đó như thế:Nhận kết quả của phương thức không đồng bộ

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp(); 
    return await OtherClass.ProcessAsync(r); 
} 

Và tôi muốn cung cấp thay thế đồng bộ:

public static ReturnResultClass GetBasicResponse() 
{ 
    return GetBasicResponseAsync().Result; 
} 

Nhưng nó khối trên Result gọi. Bởi vì nó được gọi trên cùng một luồng như một hoạt động không đồng bộ. Làm thế nào tôi có thể nhận được kết quả đồng bộ?

Cảm ơn!

Trả lời

8

Bạn nói đúng, nếu bạn đang sử dụng ứng dụng GUI, phần tiếp theo của phương thức async sẽ thực thi trên luồng giao diện người dùng theo mặc định. Và nếu bạn thực hiện việc chờ đồng bộ cho cùng một Tác vụ trên chuỗi giao diện người dùng cùng một lúc, bạn sẽ bị bế tắc.

Nếu đó là ứng dụng của bạn, bạn có thể giải quyết điều này bằng cách đơn giản là không chờ nhiệm vụ đồng bộ.

Nếu bạn chỉ đang viết một thư viện, bạn có thể sửa lỗi này bằng cách sử dụng ConfigureAwait(false). Bằng cách này, phần tiếp tục của phương thức sẽ không thực thi trên ngữ cảnh đã capture (luồng UI trong các ứng dụng GUI), mà thay vào đó là một luồng ThreadPool.

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp().ConfigureAwait(false); 
    return await OtherClass.ProcessAsync(r).ConfigureAwait(false); 
} 

Tất nhiên, giải pháp lý tưởng là không sử dụng hoạt động đồng bộ trong GUI ứng dụng của bạn sử dụng ConfigureAwait() trong thư viện của bạn, vì vậy mà những người khác có thể sử dụng phiên bản đồng bộ của các phương pháp, nếu họ muốn.

+0

Cảm ơn! 'ConfigureAwait' có ảnh hưởng đến các ứng dụng không đồng bộ của lib của tôi không? Tôi có nghĩa là, sẽ hoạt động async ở lại async, hoặc họ sẽ được thực hiện trên thread khác cho tất cả khách hàng? – gor

+0

Có, nó cũng sẽ ảnh hưởng đến khách hàng không đồng bộ, nhưng theo cách nào đó sẽ ổn. Các hoạt động async sẽ vẫn không đồng bộ, nó chỉ là phần tiếp tục của mã sử dụng 'ConfigureAwait()' sẽ không thực hiện trên luồng UI. Nhưng bất kỳ mã async nào trong các phương thức bắt đầu trên chuỗi giao diện người dùng sẽ vẫn ở đó (trừ khi bạn sử dụng 'ConfigureAwait()' ở đó cũng vậy). – svick

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