开发者

Is Wait() necessary after using Task.Factory.StartNew()?

Almost all documentation that I have seen on using the C# 4.0 Task.Factory.StartNew states that in order to wait for the Task to complete, you need a Wait. But my initial testing shows that it is unnecessary. Can anyone else give me confirmation on this? I'm curious as to why so much online and printed references say you should call Wa开发者_运维问答it.

Here's a simple console app that shows that I don't need the Wait statement, so I commented it out. Whether or not I comment out the tsk.Wait(), the output is the same.

Expected output in all cases is as follows:

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

The code:

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();
    }
}


If you just want to wait for the task to finish, the recommended course of action is to call .Wait(). For a Task (as opposed to a Task<T>) this is the only option.

For a Task<T>, however, there is also .Result, which also waits, and that is what you are using. So in your case it is unnecessary to call .Wait().


One important feature of Wait is that it acts as a rendezvous point in that any exception thrown by the Task will be re-throw at this point. As the current Task implementation* forces you to observe any such exception Wait is a good option for doing so. You can, however, also observe the exception by querying the Task instance for an exception.

*) Apparently this will be changed. The behavior is changed in the Async CTP.


Since according to this, accessing the Value of the Task ensures that the task is completed, you're right that it's not required.


As Timwi stated, .Result also waits. Since you are using tsk.Result in your Console.WriteLine call, you are doing the wait as a side-effect.

It also depends on how long it takes the task to complete. If it is very short, you may not realize the need for .Wait, because it seems to always finish in time. There is danger in leaving it out if you need the task to complete before continuing. The .Wait should therefore be used even if 99% of the time, it doesn't actually result in any time being spent waiting.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜