Task.Run 和 Task.Factory.StartNew 都可以把一段要执行的代码放到ThreadPool thread中去执行。Task.Factory.StartNew是.Net 4.0中引入的,而Task.Run则是在.Net 4.5中引入,首要目的是为了简化Task.Factory.StartNew的使用。简言之,

Task.Run(someAction)

Task.Factory.StartNew(someAction, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

是基本等价的。

说基本等价,是因为这两种用法还是有不完全相同的地方。

比如下面的代码

var t = Task.Factory.StartNew(delegate{return 42;}); 

通过Task.Factory.StartNew ,我们把一个TResult是int的delegate变成了Task<int>类型。

那么下面的代码呢

var t = Task.Factory.StartNew(async delegate
{await Task.Delay(1000);return 42;
});

传给Task.Factory.StartNew的是一个asyn的delegate,即是Task<int>类型。通过Task.Factory.StartNew,得到的t是一个Task<Task<int>>类型。

这时候,如果我们await t,实际上,当它返回时,并不是这个async的delegate执行完成了,而是得到了Task<int>。这通常不是我们想要的结果。

为了处理这种情况,.Net 4引入了Unwrap函数。Unwrap有两个重载方法,一个是作用于类型Task<Task>上,另外一个是作用于Task<Task<TResult>>上。

在Task<Task>上调用Unwrap会返回一个新的Task,它代表这内部Task最终是否完成。

回到前面的例子,如果我想让t代表内部的async delegate,那么可以这样

var t = Task.Factory.StartNew(async delegate
{await Task.Delay(1000);return 42;
}).Unwrap();

接下来讲Task.Run。由于上面所述的用法是一种很常见的需求,因此在.Net 4.5中,

var t = Task.Run(async delegate
{await Task.Delay(1000);return 42;
});

上述代码就直接得到的是Task<int>,而不是Task<Task<int>>。

即该代码等价于

var t = Task.Factory.StartNew(async delegate
{ await Task.Delay(1000);  return 42;
}, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap();

转载于:https://www.cnblogs.com/wangguangxin/p/4032678.html

Task.Run vs Task.Factory.StartNew相关推荐

  1. Task.Run Vs Task.Factory.StartNew z

    在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...

  2. C# Task.Run 和 Task.Factory.StartNew 区别

    有小伙伴问我,为什么不推荐他使用 Task.Factory.StartNew ,因为 Task.Run 是比较新的方法. 本文告诉大家 Task.Run 和 Task.Factory.StartNew ...

  3. 一次Task.Run异常问题的排查

    最近在测试一个功能代码时发现一个非常奇怪的问题,主要是Task.Run引起一些不符合逻辑的错误,以下针对这一问题排查的总结. 问题代码 可以建个控制台程序来运行以下代码 class Program{s ...

  4. Task.Factory.StartNew 和 Task.Run 到底有什么区别?

    前言 Task.Factory.StartNew 和 Task.Run 都可以创建 Task: Task.Factory.StartNew(() => { Console.WriteLine(& ...

  5. 单线程任务 Task.Factory.StartNew 封装

    代码: using log4net; using SunCreate.CombatPlatform.Security; using System; using System.Collections.G ...

  6. Task.Factory.StartNew 和 Task.Factory.FromAsync 有什么区别?

    咨询区 soleiljy 假设我们有一个涉及IO操作的方法 (读取数据库),这个方法支持以同步或者异步的方式执行. 同步方式 IOMethod() 异步方式 BeginIOMethod()  EndI ...

  7. 对 精致码农大佬 说的 Task.Run 会存在 内存泄漏 的思考

    一:背景 1. 讲故事 这段时间项目延期,加班比较厉害,博客就稍微停了停,不过还是得持续的技术输出呀!园子里最近挺热闹的,精致码农大佬分享了三篇文章: 为什么要小心使用 Task.Run   [htt ...

  8. 小心使用 Task.Run 续篇

    关于前两天发布的文章:为什么要小心使用 Task.Run,对文中演示的示例到底会不会导致内存泄露,给很多人带来了疑惑.这点我必须向大家道歉,是我对导致内存泄漏的原因没描述和解释清楚,也没用实际的示例证 ...

  9. C# Task 循环任务_C# Task.Run调用外部参数

    首先讲一下: c# Task启动带参数和返回值的方法: Task启动带参数 Task.Run(() => test("123")); public void Test(str ...

最新文章

  1. PyTorch中文版官方教程来啦(附下载)
  2. 学习Kali Linux必须知道的几点
  3. DELPHI - Delphi 2007 已内部支持 GIF 动画了
  4. php Session存储到Redis的方法
  5. android 系统状态栏的隐藏和显示
  6. NoSQL-MongoDB with python
  7. uva 10396——Vampire Numbers
  8. [深入React] 1. 开发环境搭建
  9. 单片机两个IO口控制三个LED灯
  10. 如何让select选项的那个请选择不被选中
  11. 计算机毕业设计Java大学生旅游拼团网站(源码+系统+mysql数据库+lw文档)
  12. Android集成FBReader(精简版)指南
  13. php7 error reporting,php中的error_reporting(7)的含义
  14. 驯服最难以捉摸的野兽──创新
  15. 医美面膜商城小程序开发,助力企业数字化转型
  16. 使用xamarin开发Android、iOS报错failed to open directory: 系统找不到指定的文件
  17. PS(PhotoShop)替换纯色图片的颜色
  18. java nmt_强大的nmt
  19. 计算机照片无法打开,提示windows照片查看器无法打开此图片怎么处理
  20. 前端面试计网、HTTP协议,操作系统(自留,持续更新)

热门文章

  1. 2018微信年度数据报告:00后最爱表情捂脸哭 80后呲牙笑
  2. “蚁人”不再是科幻!MIT最新研究,能把任何材料物体缩小1000倍 | Science
  3. 全球公有云巨头:亚马逊 AWS
  4. IBM:物联网应重启,否则注定会失望
  5. 这有5种来自大自然「馈赠」的AI技术及其应用,你知道多少?
  6. 程序员的抱枕也太高大上了吧! | 每日趣闻
  7. 酷派奖励程序员10 万股期权!因代码贡献受 Linux 之父亲自点名赞赏
  8. 烦人的Null,你可以走开点了
  9. 为何把日志打印到控制台很慢?
  10. phpstudy下的mysql升级