【问题标题】:Is Wait() necessary after using Task.Factory.StartNew()?使用Task.Factory.StartNew()后是否需要Wait()?
【发布时间】:2011-01-12 19:23:00
【问题描述】:

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

这是一个简单的控制台应用程序,显示我不需要 Wait 语句,因此我将其注释掉。不管我注释掉tsk.Wait(),输出都是一样的。

所有情况下的预期输出如下:

主线程启动。 运行 MyTask 后。结果为真 运行 SumIt 后。结果是 1 主线程结束。

代码:

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

【问题讨论】:

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


    【解决方案1】:

    如果您只想等待任务完成,推荐的做法是致电.Wait()。对于Task(相对于Task&lt;T&gt;),这是唯一的选择。

    然而,对于Task&lt;T&gt;,还有.Result等待,这就是你正在使用的。所以在你的情况下,没有必要打电话给.Wait()

    【讨论】:

    • 谢谢,蒂姆维。我脑子里放了个屁,没有注意到我使用的是 Task 而不是 Task。现在说得通了!
    【解决方案2】:

    Wait 的一个重要特性是它充当集合点,Task 抛出的任何异常都将在此时重新抛出。由于当前的Task 实现* 迫使您观察任何此类异常Wait 是这样做的好选择。但是,您也可以通过在 Task 实例中查询异常来观察异常。

    *) 显然这将被改变。异步 CTP 中的行为已更改。

    【讨论】:

      【解决方案3】:

      由于根据this,访问TaskValue确保任务完成,你是对的,它不是必需的。

      【讨论】:

      • 没错。谢谢,雅各布!我的错误是我忘记了我使用的是 Task 而不是 Task。
      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-07
        • 2011-10-28
        • 1970-01-01
        • 2018-04-02
        • 2021-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多