2011-01-12 40 views
9

Hầu như tất cả tài liệu mà tôi đã thấy khi sử dụng C# 4.0 Task.Factory.StartMở trạng thái đó để đợi cho Tác vụ hoàn tất, bạn cần một Chờ. Nhưng thử nghiệm ban đầu của tôi cho thấy rằng nó là không cần thiết. Bất cứ ai khác có thể cho tôi xác nhận về điều này? Tôi tò mò là tại sao rất nhiều tài liệu tham khảo trực tuyến và in nói rằng bạn nên gọi Chờ.Chờ() cần thiết sau khi sử dụng Task.Factory.StartNew()?

Đây là một ứng dụng giao diện điều khiển đơn giản cho thấy rằng tôi không cần câu lệnh Chờ, vì vậy tôi đã nhận xét. Có hay không tôi nhận xét ra tsk.Wait(), đầu ra là như nhau.

sản lượng dự kiến ​​trong mọi trường hợp như sau:

 
Main thread starting. 
After running MyTask. The result is True 
After running SumIt. The result is 1 
Main thread ending. 

Mã:

class Program 
{ 
    // A trivial method that returns a result and takes no arguments. 
    static bool MyTask() 
    { 
     Thread.Sleep(2000); 
     return true; 
    } 

    // This method returns the summation of a positive integer 
    // which is passed to it. 
    static int SumIt(object v) 
    { 
     int x = (int)v; 
     int sum = 0; 
     for (; x > 0; x--) 
      sum += x; 
     return sum; 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("Main thread starting."); 
     // Construct the first task. 
     Task<bool> tsk = Task<bool>.Factory.StartNew(() => MyTask()); 
     // I found this Wait statement to be completely unnecessary. 
     //tsk.Wait(); 
     Console.WriteLine("After running MyTask. The result is " + 
     tsk.Result); 
     // Construct the second task. 
     Task<int> tsk2 = Task<int>.Factory.StartNew(() => SumIt(1)); 
     Console.WriteLine("After running SumIt. The result is " + 
     tsk2.Result); 
     tsk.Dispose(); 
     tsk2.Dispose(); 
     Console.WriteLine("Main thread ending."); 
     Console.ReadLine(); 
    } 
} 

Trả lời

19

Nếu bạn chỉ muốn đợi công việc hoàn thành, quá trình hành động được khuyến nghị là gọi .Wait(). Đối với một Task (như trái ngược với Task<T>), đây là tùy chọn duy nhất.

Tuy nhiên, cũng có .Result, trong đó cũng là chờ và đó là những gì bạn đang sử dụng. Vì vậy, trong trường hợp của bạn nó là không cần thiết để gọi .Wait().

+0

Cảm ơn, Timwi. Tôi đã có một rắm não và không nhận thấy rằng tôi đã sử dụng Task thay vì Task. Bây giờ nó có ý nghĩa! –

+0

@tambui: cách đánh dấu câu trả lời này như thế nào? – stackoverflowuser

+0

@stackoverflowuser: Rất tiếc, không biết cách. Xong ngay. –

1

Kể từ khi theo this, truy cập vào Value của Task đảm bảo rằng công việc hoàn tất, bạn' lại đúng là nó không cần thiết.

+0

Đúng vậy. Cảm ơn, Jacob! Sai lầm của tôi là tôi đã quên rằng tôi đã sử dụng Task thay vì Task. –

1

Như Timwi đã nêu, .Result cũng đợi. Vì bạn đang sử dụng tsk.Result trong cuộc gọi Console.WriteLine của bạn, bạn đang chờ đợi như là một tác dụng phụ.

Điều đó cũng tùy thuộc vào thời gian hoàn thành nhiệm vụ. Nếu nó là rất ngắn, bạn có thể không nhận ra sự cần thiết. Chờ đợi, bởi vì nó dường như luôn luôn kết thúc trong thời gian. Có nguy hiểm khi bỏ nó ra nếu bạn cần hoàn thành nhiệm vụ trước khi tiếp tục. Do đó, Wait nên được sử dụng ngay cả khi 99% thời gian, nó không thực sự dẫn đến bất kỳ thời gian nào đang chờ đợi.

2

Một tính năng quan trọng của Wait là nó hoạt động như điểm hẹn trong bất kỳ ngoại lệ nào được ném bởi Task sẽ được ném lại vào thời điểm này. Khi thực hiện Task hiện tại * buộc bạn phải quan sát bất kỳ ngoại lệ nào như vậy Wait là một tùy chọn tốt để làm như vậy. Tuy nhiên, bạn cũng có thể quan sát ngoại lệ bằng cách truy vấn cá thể Task cho một ngoại lệ.

*) Rõ ràng điều này sẽ được thay đổi. Hành vi được thay đổi trong Async CTP.

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