使用Task.Factory.StartNew()后是否还需要Wait()?
我见过的关于使用 C# 4.0 Task.Factory.StartNew 的几乎所有文档都指出,为了等待任务完成,您需要等待。但我的初步测试表明这是没有必要的。其他人可以给我确认吗?我很好奇为什么这么多在线和印刷参考资料说你应该打电话等待。
这是一个简单的控制台应用程序,显示我不需要 Wait 语句,因此我将其注释掉。无论我是否注释掉 tsk.Wait(),输出都是相同的。
所有情况下的预期输出如下:
Main thread starting. After running MyTask. The result is True After running SumIt. The result is 1 Main thread ending.
代码:
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();
}
}
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 Wait.
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您只想等待任务完成,建议的操作过程是调用
.Wait()
。对于Task
(与Task
相对),这是唯一的选项。然而,对于
Task
,还有.Result
,它也等待,而这正是您正在使用的。因此,在您的情况下,无需调用.Wait()
。If you just want to wait for the task to finish, the recommended course of action is to call
.Wait()
. For aTask
(as opposed to aTask<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()
.Wait
的一个重要功能是,它充当集合点,因为Task
抛出的任何异常都将在此时重新抛出。由于当前的Task
实现*强制您观察任何此类异常,Wait
是这样做的一个不错的选择。不过,您也可以通过查询Task
实例来观察异常。*)显然这将会改变。异步 CTP 中的行为已更改。
One important feature of
Wait
is that it acts as a rendezvous point in that any exception thrown by theTask
will be re-throw at this point. As the currentTask
implementation* forces you to observe any such exceptionWait
is a good option for doing so. You can, however, also observe the exception by querying theTask
instance for an exception.*) Apparently this will be changed. The behavior is changed in the Async CTP.
由于根据 this,访问
Value
Task
确保任务完成,你是对的,这不是必需的。Since according to this, accessing the
Value
of theTask
ensures that the task is completed, you're right that it's not required.正如 Timwi 所说,.Result 也在等待。由于您在 Console.WriteLine 调用中使用 tsk.Result,因此等待是一种副作用。
它还取决于完成任务需要多长时间。如果它很短,您可能没有意识到需要 .Wait,因为它似乎总是及时完成。如果您需要在继续之前完成任务,则将其忽略是有危险的。因此,即使在 99% 的情况下,也应该使用 .Wait,它实际上不会导致任何时间花在等待上。
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.