Câu trả lời của SLaks và Killercam là tốt; Tôi nghĩ rằng tôi chỉ cần thêm một chút bối cảnh.
Câu hỏi đầu tiên của bạn về cơ bản là về những phương pháp có thể được đánh dấu async
.
Một phương thức được đánh dấu là async
có thể trả về void
, Task
hoặc Task<T>
. Sự khác biệt giữa chúng là gì?
Một Task<T>
phương thức async trở lại có thể được chờ đợi và khi tác vụ hoàn thành, nó sẽ tạo ra một chữ T.
Một Task
phương thức async trở lại có thể được chờ đợi và khi tác vụ hoàn thành, việc tiếp tục tác vụ được lên lịch để chạy.
Một void
phương thức async trở lại không thể được chờ đợi; đó là một phương pháp "lửa và quên". Nó hoạt động không đồng bộ và bạn không có cách nào để biết khi nào nó được thực hiện. Điều này là nhiều hơn một chút kỳ lạ; như SLaks nói, thông thường bạn sẽ chỉ làm điều đó khi thực hiện một trình xử lý sự kiện không đồng bộ. Sự kiện cháy, người xử lý thực hiện; không ai sẽ "chờ đợi" nhiệm vụ được trả về bởi trình xử lý sự kiện vì các trình xử lý sự kiện không trả lại các tác vụ và ngay cả khi chúng đã thực hiện, mã nào sẽ sử dụng Tác vụ cho việc gì? Đó thường không phải là mã người dùng chuyển điều khiển đến trình xử lý ở vị trí đầu tiên.
Câu hỏi thứ hai của bạn, trong một bình luận, về cơ bản là về những gì có thể được await
ed:
Những loại phương pháp có thể được await
ed? Một phương thức void-return có thể được await
ed không?
Không, một phương thức trả về khoảng trống không thể được chờ đợi. Trình biên dịch chuyển await M()
thành một cuộc gọi đến M().GetAwaiter()
, trong đó GetAwaiter
có thể là một phương thức thể hiện hoặc một phương thức mở rộng. Giá trị được chờ đợi phải là một giá trị mà bạn có thể nhận được một người phục vụ; rõ ràng một phương thức trả về khoảng trống không tạo ra một giá trị mà từ đó bạn có thể nhận được một người phục vụ.
Task
phương pháp trả lại có thể tạo ra các giá trị chờ đợi. Chúng tôi dự đoán rằng các bên thứ ba sẽ muốn tạo ra các triển khai các Task
đối tượng giống như của riêng họ có thể được chờ đợi và bạn sẽ có thể chờ đợi họ. Tuy nhiên, bạn sẽ không được phép khai báo async
các phương thức trả về bất cứ thứ gì ngoài void
, Task
hoặc Task<T>
.
(CẬP NHẬT: Câu cuối cùng của tôi có thể bị làm sai lệch bởi một phiên bản tương lai của C #; có một đề xuất cho phép các kiểu trả về khác với các loại nhiệm vụ cho các phương thức không đồng bộ.)
(CẬP NHẬT: Tính năng được đề cập ở trên đã đưa nó vào C # 7.)