Task.Run 和 Task.Factory.StartNew 区别
Task.Run 是在 dotnet framework 4.5 之后才可以使用, Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制。
可以认为 Task.Run 是简化的 Task.Factory.StartNew 的使用,除了需要指定一个线程是长时间占用的,否则就使用 Task.Run
创建新线程
下面来告诉大家使用两个函数创建新的线程
Task.Run(() =>
{
var foo = 2;
});
这时 foo 的创建就在另一个线程,需要知道 Task.Run 用的是线程池,也就是不是调用这个函数就会一定创建一个新的线程,但是会在另一个线程运行。
Task.Factory.StartNew(() =>
{
ar foo = 2;
});
可以看到,两个方法实际上是没有差别,但是Task.Run比较好看,所以推荐使用Task.Run。
等待线程
创建的线程,如果需要等待线程执行完成在继续,那么可以使用 await 等待

private static async void SeenereKousa()
{
Console.WriteLine("开始 线程"+Thread.CurrentThread.ManagedThreadId);
await Task.Run(() =>
{
Console.WriteLine("进入 线程" + Thread.CurrentThread.ManagedThreadId);
});
Console.WriteLine("退出 线程"+Thread.CurrentThread.ManagedThreadId);
}

但是需要说的是这里使用 await 主要是给函数调用的外面使用,上面代码在函数里面使用 await 函数是 void 那么和把代码放在 task 里面是相同

private static async void SeenereKousa()
{
Console.WriteLine("开始 线程"+Thread.CurrentThread.ManagedThreadId);
await Task.Run(() =>
{
Console.WriteLine("进入 线程" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("退出 线程"+Thread.CurrentThread.ManagedThreadId);
});
}

但是如果把 void 修改为 Task ,那么等待线程才有用
除了使用 await 等待,还可以使用 WaitAll 等待

Console.WriteLine("开始 线程" + Thread.CurrentThread.ManagedThreadId);
var t = Task.Run(() =>
{
Console.WriteLine("进入 线程" + Thread.CurrentThread.ManagedThreadId);
});
Task.WaitAll(t);
Console.WriteLine("退出 线程" + Thread.CurrentThread.ManagedThreadId);

使用 WaitAll 是在调用 WaitAll 的线程等待,也就是先在线程 1 运行,然后异步到 线程2 运行,这时线程1 等待线程2运行完成再继续,所以输出
- 开始 线程1
- 进入 线程2
- 退出 线程1
长时间运行
两个函数最大的不同在于 Task.Factory.StartNew 可以设置线程是长时间运行,这时线程池就不会等待这个线程回收

Task.Factory.StartNew(() =>
{
for (int i = 0; i < 100; i++)
{
var foo = 2;
}
Console.WriteLine("进行 线程" + Thread.CurrentThread.ManagedThreadId);
}, TaskCreationOptions.LongRunning);

所以在需要设置线程是长时间运行的才需要使用 Task.Factory.StartNew 不然就使用 Task.Run
调用 Task.Run(foo) 就和使用下面代码一样
Task.Factory.StartNew(foo, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); 最后再说明下await和async与Task的联系:
async标记会告诉编辑器接下来的方法可能会用到异步,当然并不一定会有用到,一直向下到await这是会等待,await 不会开启新的线程,
当前线程会一直往下走直到遇到真正的Async方法(比如说HttpClient.GetStringAsync),这个方法的内部会用Task.Run或者Task.Factory.StartNew 去开启线程(因为task底层是线程池机制,也可能是复用线程)。
如果方法不是.NET为我们提供的Async方法,我们需要自己创建Task,才会真正的去创建线程。
Task.Run 和 Task.Factory.StartNew 区别的更多相关文章
- C# Task.Run 和 Task.Factory.StartNew 区别
Task.Run 是在 dotnet framework 4.5 之后才可以使用,但是 Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制.可以认 ...
- Task.Run与Task.Factory.StartNew的区别
Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ...
- 【.NET】- Task.Run 和 Task.Factory.StartNew 区别
Task.Run 是在 dotnet framework 4.5 之后才可以使用, Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制. 可以认为 ...
- .NET - Task.Run vs Task.Factory.StartNew
翻译自 Stephen Toub 2011年10月24日的博文<Task.Run vs Task.Factory.StartNew>,Stephen Toub 是微软并行计算平台团队的首席 ...
- Task.Run Vs Task.Factory.StartNew
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
- Task.Run Vs Task.Factory.StartNew z
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
- Task.Run Vs Task.Factory.StartNew 【收藏】
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
- Task.Run 和 Task.Factory.StartNew
在.Net 4中,Task.Factory.StartNew是启动一个新Task的首选方法.它有很多重载方法,使它在具体使用当中可以非常灵活,通过设置可选参数,可以传递任意状态,取消任务继续执行,甚至 ...
- .Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法
前言 .NET4.0下是没有Task.Run及Task.Delay方法的,而.NET4.5已经实现,对于还在使用.NET4.0的同学来说,如何在.NET4.0下实现这两个方法呢? 在.NET4.0下, ...
随机推荐
- Quartz.Net入门 - Net作业调度
背景 很多时候,项目需要在不同时刻,执行一个或很多个不同的作业. Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架. 介绍 Quartz一个开源 ...
- Noip2013(普及组) 车站分级
题目描述 一条单向的铁路线上,依次有编号为 , , …, n 的 n 个火车站.每个火车站都有一个级别,最低为 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x, ...
- 乐字节Java变量与数据结构之二:Java常量与变量
大家好,小乐又来给大家讲述Java基础知识.上次说了乐字节Java变量与数据类型之一:Java编程规范,关键字与标识符,这次将接着往下说,谈谈Java常量与变量. 1.常量 1).定义 在程序执行的过 ...
- Elasticsearch集群搭建笔记(elasticsearch-6.3.0)
# 检查Java版本 java -version # 安装Elasticsearch,所有节点均安装并解压 wget https://artifacts.elastic.co/downloads/el ...
- iOS开发支付篇——内购(IAP)详解
1 <em>内购所需要的资料整理总结,史上最完整的,哈哈哈哈哈哈</em> 思维导图 重点总结: 1 2 3 4 5 6 7 8 9 10 11 12 13 1.获取内购列表( ...
- LeetCode. 阶乘后的零
题目要求: 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例: 输入: 3 输出: 0 解释: 3! = 6, 尾数中没有零. 解法: class Solution { public: int ...
- TZOJ数据结构实验:左叶子之和
int sumOfLeftLeaves(struct TreeNode* root) { if (root == NULL) { ; }//递归结束条件 if (root->left & ...
- go 函数 命名返回值
Go 的返回值可以被命名,并且像变量那样使用. 返回值的名称应当具有一定的意义,可以作为文档使用. 没有参数的 return 语句返回结果的当前值.也就是`直接`返回. 直接返回语句仅应当用在像下面这 ...
- awr报告没有数据11.2.0.3
有个朋友,反馈AWR没有数据: 咨询版本:oracle企业版本11.2.0.3 SQL> select * from v$version; BANNER -------------------- ...
- Linux发布java jar包
打包参考https://www.cnblogs.com/Rexcnblog/p/11357146.html 刚打包出来新鲜的jar 然后开始一顿猛如虎的操作了,把打包的jar和对用的sh文件拷贝到li ...