Sự khác biệt giữa .Wait () so với .GetAwaiter (). GetResult () là gì?


89

Phương thức của tôi trả về Task. Tôi muốn đợi cho đến khi nó hoàn thành. Tôi nên sử dụng .Wait()hoặc .GetAwaiter().GetResult()? sự khác biệt giữa chúng là gì?

Câu trả lời:


108

Cả hai đều là sự chờ đợi đồng bộ cho kết quả của hoạt động (và bạn nên tránh những điều đó nếu có thể).

Sự khác biệt chủ yếu là trong việc xử lý các trường hợp ngoại lệ. Với Wait, dấu vết ngăn xếp ngoại lệ không bị thay đổi và đại diện cho ngăn xếp thực tế tại thời điểm ngoại lệ, vì vậy nếu bạn có một đoạn mã chạy trên một chuỗi nhóm luồng, bạn sẽ có một ngăn xếp như

ThreadPoolThread.RunTask
YourCode.SomeWork

Mặt khác, .GetAwaiter().GetResult()sẽ làm lại dấu vết ngăn xếp để xem xét tất cả ngữ cảnh không đồng bộ, bỏ qua rằng một số phần của mã thực thi trên luồng UI và một số phần trên luồng ThreadPool, và một số chỉ là I / O không đồng bộ. Vì vậy, dấu vết ngăn xếp của bạn sẽ phản ánh một bước giống như đồng bộ thông qua mã của bạn :

TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork

Điều này có xu hướng làm cho các dấu vết ngăn xếp ngoại lệ hữu ích hơn rất nhiều, ít nhất là. Bạn có thể thấy nơi YourCode.SomeWorkđược gọi trong ngữ cảnh ứng dụng của bạn , thay vì "cách thực tế mà ứng dụng được chạy".

Một ví dụ về cách hoạt động của điều này là trong nguồn tham khảo (tất nhiên là không theo hợp đồng).


6
Task.GetAwaiter () trả về một TaskAwaiter . Tuy nhiên, tài liệu cho TaskAwaiter.GetResult () khuyên: "API này hỗ trợ cơ sở hạ tầng sản phẩm và không nhằm mục đích sử dụng trực tiếp từ mã của bạn." Bạn có thể nhận xét?
DavidRR

23
@DavidRR Toàn bộ TaskAwaiterlà chi tiết triển khai. Mặt khác, cơ chế / awaiter awaitable là tài liệu, và sử dụng vịt-gõ - GetAwaiterawaitnhư GetEnumeratorforeachhoặc Disposeusing. Tất cả điều này được định nghĩa trong đặc tả C # bất kể bộ chờ cụ thể đang được sử dụng - lưu ý rằng Task.GetAwaiter"dành cho việc sử dụng trình biên dịch hơn là để sử dụng trong mã ứng dụng." Nhưng vấn đề là mục đích sử dụng là để làm await, không phải Wait()cũng không GetAwaiter().GetResult()- nhưng GetResultcung cấp cho bạn những ngăn xếp đẹp hơn nếu bạn cần.
Luaan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.