当前位置:  开发笔记 > 编程语言 > 正文

为什么Task.Factory.StartNew会在Task.Run没有的情况下立即返回?

如何解决《为什么Task.Factory.StartNew会在Task.Run没有的情况下立即返回?》经验,为你挑选了2个好方法。

请考虑以下代码段:

Task[] tasks = new Task[4];
for (var i = 0; i < tasks.Length; ++i) {
    tasks[i] = Task.Run(async () =>
    {
        await Task.Delay(4000);
    });
}
for (var i = 0; i < tasks.Length; ++i)
    await tasks[i];

Console.WriteLine("Done!");

这按预期工作,执行时需要4.000毫秒.但是,如果我Task.RunTask.Factory.StartNew它交换它只需要0.006毫秒!

有谁能解释为什么?



1> Stephen Clea..:

有谁能解释为什么?

简单来说,StartNew不了解async代表.

因此,当您的委托首先返回一个不完整的任务时await,请StartNew查看委托退出并认为其工作已完成.这就是它返回Task这里的原因.Task.Run具有处理异步委托的特殊逻辑,自动解包内部任务.

这只是使用StartNew异步代码的一个缺陷; 我在博客文章中详细介绍了这个以及其他内容StartNew是Dangerous.



2> FindOutIslam..:

好的,我在阅读了这篇https://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/后自己找到了答案.

通过在这里使用async关键字,编译器将把这个委托映射为Func>:调用委托将返回Task表示此调用的最终完成.因为代表是Func>,TResultTask,因此't'的类型将是Task>,而不是Task.

所以这段代码按预期工作:

Task[] tasks = new Task[4];
for (var i = 0; i < tasks.Length; ++i) {
    tasks[i] = Task.Factory.StartNew(async () =>
    {
        await Task.Delay(4000);
    });
}
for (var i = 0; i < tasks.Length; ++i)
    await await (tasks[i] as Task);

Console.WriteLine("Done!");

哪个也可以使用Unwrap:

Task[] tasks = new Task[4];
for (var i = 0; i < tasks.Length; ++i) {
    tasks[i] = Task.Factory.StartNew(async () =>
    {
        await Task.Delay(4000);
    }).Unwrap();
}
for (var i = 0; i < tasks.Length; ++i)
    await tasks[i];

Console.WriteLine("Done!");

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有