Task.Run vs Task.Factory.StartNew
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相关推荐
- Task.Run Vs Task.Factory.StartNew z
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
- C# Task.Run 和 Task.Factory.StartNew 区别
有小伙伴问我,为什么不推荐他使用 Task.Factory.StartNew ,因为 Task.Run 是比较新的方法. 本文告诉大家 Task.Run 和 Task.Factory.StartNew ...
- 一次Task.Run异常问题的排查
最近在测试一个功能代码时发现一个非常奇怪的问题,主要是Task.Run引起一些不符合逻辑的错误,以下针对这一问题排查的总结. 问题代码 可以建个控制台程序来运行以下代码 class Program{s ...
- Task.Factory.StartNew 和 Task.Run 到底有什么区别?
前言 Task.Factory.StartNew 和 Task.Run 都可以创建 Task: Task.Factory.StartNew(() => { Console.WriteLine(& ...
- 单线程任务 Task.Factory.StartNew 封装
代码: using log4net; using SunCreate.CombatPlatform.Security; using System; using System.Collections.G ...
- Task.Factory.StartNew 和 Task.Factory.FromAsync 有什么区别?
咨询区 soleiljy 假设我们有一个涉及IO操作的方法 (读取数据库),这个方法支持以同步或者异步的方式执行. 同步方式 IOMethod() 异步方式 BeginIOMethod() EndI ...
- 对 精致码农大佬 说的 Task.Run 会存在 内存泄漏 的思考
一:背景 1. 讲故事 这段时间项目延期,加班比较厉害,博客就稍微停了停,不过还是得持续的技术输出呀!园子里最近挺热闹的,精致码农大佬分享了三篇文章: 为什么要小心使用 Task.Run [htt ...
- 小心使用 Task.Run 续篇
关于前两天发布的文章:为什么要小心使用 Task.Run,对文中演示的示例到底会不会导致内存泄露,给很多人带来了疑惑.这点我必须向大家道歉,是我对导致内存泄漏的原因没描述和解释清楚,也没用实际的示例证 ...
- C# Task 循环任务_C# Task.Run调用外部参数
首先讲一下: c# Task启动带参数和返回值的方法: Task启动带参数 Task.Run(() => test("123")); public void Test(str ...
最新文章
- PyTorch中文版官方教程来啦(附下载)
- 学习Kali Linux必须知道的几点
- DELPHI - Delphi 2007 已内部支持 GIF 动画了
- php Session存储到Redis的方法
- android 系统状态栏的隐藏和显示
- NoSQL-MongoDB with python
- uva 10396——Vampire Numbers
- [深入React] 1. 开发环境搭建
- 单片机两个IO口控制三个LED灯
- 如何让select选项的那个请选择不被选中
- 计算机毕业设计Java大学生旅游拼团网站(源码+系统+mysql数据库+lw文档)
- Android集成FBReader(精简版)指南
- php7 error reporting,php中的error_reporting(7)的含义
- 驯服最难以捉摸的野兽──创新
- 医美面膜商城小程序开发,助力企业数字化转型
- 使用xamarin开发Android、iOS报错failed to open directory: 系统找不到指定的文件
- PS(PhotoShop)替换纯色图片的颜色
- java nmt_强大的nmt
- 计算机照片无法打开,提示windows照片查看器无法打开此图片怎么处理
- 前端面试计网、HTTP协议,操作系统(自留,持续更新)