使用Task.Factory.StartNew()后是否需要Wait()?

时间:2011-01-12 19:23:01

标签: c# parallel-processing task wait task-parallel-library

我在使用C#4.0 Task.Factory.StartNew时看到的几乎所有文档都指出,为了等待任务完成,您需要等待。但我的初步测试表明这是不必要的。其他人可以给我确认吗?我很好奇为什么这么多在线和印刷的参考文献都说你应该打电话给Wait。

这是一个简单的控制台应用程序,显示我不需要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();
    }
}

4 个答案:

答案 0 :(得分:19)

如果您只想等待任务完成,建议的操作方法是致电.Wait()。对于Task(而不是Task<T>),这是唯一的选择。

对于Task<T>,还有.Result等待,这就是您正在使用的内容。因此,在您的情况下,无需致电.Wait()

答案 1 :(得分:2)

Wait的一个重要特性是它充当了一个集合点,因为Task抛出的任何异常都将在此时被重新抛出。由于当前Task实现*强制您观察任何此类异常Wait是一个很好的选择。但是,您也可以通过查询Task实例来查看异常。

*)显然这会改变。在Async CTP中更改了该行为。

答案 2 :(得分:1)

根据this,访问Value的{​​{1}}可确保任务完成,您是对的,这不是必需的。

答案 3 :(得分:1)

正如蒂米威所说,.Result也在等待。由于您在Console.WriteLine调用中使用tsk.Result,因此您将等待作为副作用。

这还取决于任务完成所需的时间。如果它很短,你可能没有意识到需要。等等,因为它似乎总是及时完成。如果您需要在继续之前完成任务,则有将其遗漏的危险。因此,即使99%的时间都使用.Wait,它实际上并不会导致任何时间等待。