Bạn nhận được lỗi đó vì lớp Task
đã bắt đầu công việc trước khi gửi cho bạn. Bạn chỉ nên gọi Start
về tác vụ mà bạn tạo bằng cách gọi hàm tạo của nó và bạn thậm chí không nên làm điều đó trừ khi bạn có lý do thuyết phục để không bắt đầu tác vụ khi tạo; nếu bạn muốn nó bắt đầu ngay lập tức, bạn nên sử dụng Task.Run
hoặc Task.Factory.StartNew
để tạo và bắt đầu một Task
mới.
Vì vậy, bây giờ chúng tôi biết chỉ cần loại bỏ điều đó pesky Start
. Bạn sẽ chạy mã của bạn và thấy rằng hộp thông báo được hiển thị ngay lập tức, không phải 5 giây sau đó, có chuyện gì với điều đó?
Vâng, Task.Delay
chỉ cung cấp cho bạn một tác vụ sẽ được hoàn thành sau 5 giây. Nó không ngừng thực hiện chủ đề trong 5 giây. Những gì bạn muốn làm là có một số mã được thực hiện sau khi nhiệm vụ đó kết thúc. Đó là những gì ContinueWith
dành cho. Nó cho phép bạn chạy một số mã sau khi một công việc nhất định được thực hiện:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
Điều này sẽ hoạt động như mong đợi.
Chúng tôi cũng có thể tận dụng await
từ khóa C# 5.0 để thêm continuations dễ dàng hơn:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
Trong khi giải thích đầy đủ về những gì đang xảy ra ở đây là ngoài phạm vi của câu hỏi này, kết quả cuối cùng là một phương pháp hoạt động rất giống với phương pháp trước; nó sẽ hiển thị một hộp thông báo 5 giây sau khi bạn gọi phương thức, nhưng chính phương thức đó sẽ trả về [gần như] ngay lập tức trong cả hai trường hợp. Điều đó nói rằng, await
là rất mạnh mẽ, và cho phép chúng tôi viết các phương pháp có vẻ đơn giản và dễ hiểu, nhưng điều đó sẽ khó khăn hơn và phức tạp hơn để viết trực tiếp bằng cách sử dụng ContinueWith
. Nó cũng đơn giản hóa rất nhiều việc xử lý lỗi, lấy ra rất nhiều mã soạn sẵn.
Calling 'Wait() 'trên một nhiệm vụ sẽ chặn thread hiện tại cho đến khi nhiệm vụ được giải quyết. Đó là gần như không bao giờ những gì bạn muốn xảy ra. – Jeremy
@Jeremy: Thật vậy, đáng chú ý đến hành vi mà bạn đã đề cập, nhưng trong trường hợp này, FunctionA của anh ấy đã chặn luồng hiện tại, vì vậy tôi cho rằng anh ấy đang tìm cách xác định thời điểm tác vụ đã hoàn thành. Để làm rõ sự khác biệt giữa Chờ và không đồng bộ (đối với người đọc trong tương lai), vui lòng đọc [link] này (http://stackoverflow.com/questions/9519414/whats-the-difference-between-task-start-wait-and-async- đang chờ đợi) – Sergiu