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

发布于 2024-10-11 20:36:13 字数 1562 浏览 6 评论 0原文

我见过的关于使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半枫 2024-10-18 20:36:13

如果您只想等待任务完成,建议的操作过程是调用 .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 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().

紅太極 2024-10-18 20:36:13

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 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.

踏月而来 2024-10-18 20:36:13

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

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

丢了幸福的猪 2024-10-18 20:36:13

正如 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文