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.
精彩评论