2015-12-31 25 views
11

Tôi đang cố gắng tìm cách thực hành tốt nhất cho một trong các dự án của tôi. Nó là một ứng dụng WPF điển hình với một giao diện người dùng hiển thị một danh sách các mục và có một dịch vụ dữ liệu trả về kết quả.Async đang chờ vs GetAwaiter(). GetResult() và gọi lại

Chúng tôi đang gọi dịch vụ không đồng bộ để không chặn giao diện người dùng. Chúng tôi có 2 lựa chọn trước mặt chúng tôi:

  1. Sử dụng Async chờ từ khóa Điều này đòi hỏi đánh dấu tất cả các phương pháp async từ nút bấm tất cả các cách để phục vụ lớp (class về phía khách hàng mà làm cho các cuộc gọi http đến máy chủ) và bất kỳ phương pháp nào ở giữa. Cách tiếp cận này hoạt động tốt khác sau đó vấn đề tuyên truyền async ở khắp mọi nơi

  2. Sử dụng awaiter và gọi lại Trong phương pháp này, trình khách UI gọi lớp dịch vụ và chuyển một cuộc gọi lại đến lớp dịch vụ, lớp dịch vụ kết thúc cuộc gọi http đến máy chủ trong một nhiệm vụ và sử dụng GetAwaiter() GetResult(), khi cuộc gọi http được hoàn thành, nó sẽ gọi lại cuộc gọi được truyền bởi trình khách UI. Trong trường hợp này, không có phương pháp nào được đánh dấu là không đồng bộ, nhưng không thực sự chắc chắn về việc sử dụng GetAwaiter()

    Task.Run (async() => // await http call, gọi lại gọi lại) .GetAwaiter(). GetResult ();

Tôi chỉ cố gắng để tìm hiểu đó là một cách tiếp cận tốt hơn và nếu có một số vấn đề với một trong hai phương pháp mà tôi cần phải nhận thức

+1

Tôi khá chắc chắn cách tiếp cận thứ hai có thể dẫn đến khóa chết một lần trong một thời gian. Tôi biết vì tôi đã đối mặt với một cái gì đó giống nhau khi phát triển với Windows Universal. – Felype

+0

Ngoài ra còn có câu hỏi về ngoại lệ. Tôi biết với một thực hiện async đầy đủ, bạn nhận được 'AggregateException' ở cuối, nhưng tôi không biết điều gì sẽ xảy ra với các ngoại lệ trong phương thức' GetAwaiter' – Eris

+0

@Eris Khi bạn chờ đợi bạn không nhận được 'AggregateException'. Bạn nhận được ngoại lệ bên trong. Điều tương tự cũng xảy ra với 'GetResult'. – i3arnon

Trả lời

16

Bạn nên sử dụng asyncawait từ khóa tất cả các con đường lên hoặc bạn không nên sử dụng đồng bộ.

Tùy chọn thứ hai của bạn không thực sự không đồng bộ. Nó gọi một hoạt động không đồng bộ và chặn nó một cách đồng bộ với task.GetAwaiter().GetResult(). Trên đầu trang của rất phức tạp nó không phải là không đồng bộ và có thể dẫn đến deadlocks.

+0

Bạn có một số thông tin cơ bản về lý do tại sao nó có thể gây ra deadlocks? Tôi cũng đã trải nghiệm điều này, nhưng tôi đang tìm một số thông tin chuyên sâu hơn về lý do tại sao điều này xảy ra hoặc cách hoạt động của nó. –

+2

@FrederikGheysels http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – i3arnon

+0

Nghe như lời khuyên tuyệt vời, ngoại trừ tôi bị kẹt với API này từ Azure Active Directory (TokenCache) yêu cầu hoạt động đồng bộ. Bạn không thể trở về từ 'BeforeAccessNotification' cho đến khi bạn đọc cache và bạn không thể trở về từ 'AfterAccessNotification' cho đến khi bạn viết cache. Lời khuyên của bạn là gì khi bạn bị buộc vào một API đồng bộ và cần truy cập một tệp? –

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