C# Task TaskFactory 异步线程/异步任务
Task是.NetFramework3.0出现的,线程是基于线程池,然后提供了丰富的API
TaskFactory 提供对创建和计划 Task 对象的支持
创建和启动异步任务
1、Task task = new Task(() => ThreadPoolHelper.DoSomeThing());
task.Start();
2、Task task = Task.Run(() => ThreadPoolHelper.DoSomeThing());
3、TaskFactory taskFactory = Task.Factory;
Task task = taskFactory.StartNew(() => ThreadPoolHelper.DoSomeThing());
Task的线程是源于线程池 ,假如说我想控制下Task的并发数量,该怎么做?
{
//ThreadPool.SetMaxThreads(8, 8);
//线程池是单例的,全局唯一的
//设置后,同时并发的Task只有8个;而且线程是复用的;
//全局的,请不要这样设置!!!
for (int i = ; i < ; i++)
{
int k = i;
Task.Run(() =>
{
Console.WriteLine($"This is k={k},i={i} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("")}");
Thread.Sleep();
});
}
}
运行上面的代码我们发现几个需要注意的地方:
1、i的值等于100,因为异步线程的启动并不阻塞主线程;
2、使用ThreadPool.SetMaxThreads 方法 设置后,虽然能达到效果,但是线程池是单例的,全局唯一的,这样设置会影响整个程序;
那么如何实现?
{
List<Task> taskList = new List<Task>();
for (int i = ; i < ; i++)
{
int k = i;
if (taskList.Count(t => t.Status != TaskStatus.RanToCompletion) >= )
{
Task.WaitAny(taskList.ToArray());
taskList = taskList.Where(t => t.Status != TaskStatus.RanToCompletion).ToList();
}
taskList.Add(Task.Run(() =>
{
Console.WriteLine($"This is {k} running ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("")}");
Thread.Sleep();
}));
}
}
使用Parallel也可以实现
Task常用方法
1、Delay(Int32)、Delay(Int32, CancellationToken)、Delay(TimeSpan)、Delay(TimeSpan, CancellationToken)
在指定的时间后执行任务
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine("在Delay之前");
Task.Delay().ContinueWith(t => { Console.WriteLine($"Delay耗时ContinueWith Start{stopwatch.ElapsedMilliseconds}"); ThreadPoolHelper.DoSomeThing(); Console.WriteLine($"Delay耗时ContinueWith End{stopwatch.ElapsedMilliseconds}"); });
Console.WriteLine($"Delay耗时{stopwatch.ElapsedMilliseconds}");
}
2、ContinueWith(Action<Task,Object>, Object)、ContinueWith(Action<Task>)、ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)、...
目标任务完成后异步执行一个延续任务
3、Wait()、Wait(CancellationToken)、Wait(Int32)、Wait(Int32, CancellationToken)、Wait(TimeSpan)
等待任务或经过指定时间为止 与Thread.Join方法、waitHandle.WaitOne方法 作用相当
4、WaitAll(Task[])、WaitAll(Task[], CancellationToken)、WaitAll(Task[], Int32)、WaitAll(Task[], Int32, CancellationToken)、WaitAll(Task[], TimeSpan)
等待所有任务对象完成执行或经过指定时间为止,或等到取消等待
5、WaitAny(Task[])、WaitAny(Task[], CancellationToken)、WaitAny(Task[], Int32)、WaitAny(Task[], Int32, CancellationToken)、WaitAny(Task[], TimeSpan)
等待所有任务对象任何一个任务对象完成执行或经过指定时间为止,或等到取消标记取消
6、WhenAll(IEnumerable<Task>)、WhenAll(Task[])、WhenAll<TResult>(IEnumerable<Task<TResult>>)、WhenAll<TResult>(Task<TResult>[])
所有任务对象都已完成时,创建一个新的任务并执行
7、WhenAny(IEnumerable<Task>)、WhenAny(Task[])、WhenAny<TResult>(IEnumerable<Task<TResult>>)、WhenAny<TResult>(Task<TResult>[])
所有任务对象任何一个任务完成就创建一个新的任务并执行
TaskFactory常用方法
1、ContinueWhenAll(Task[], Action<Task[]>)、ContinueWhenAll(Task[], Action<Task[]>, CancellationToken)、ContinueWhenAll(Task[], Action<Task[]>, CancellationToken, TaskContinuationOptions, TaskScheduler)、...
所有任务对象都已完成时,创建一个新的任务并执行 与Task.WhenAll方法 作用相当
2、ContinueWhenAny(Task[], Action<Task>)、ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[], Action<Task<TAntecedentResult>>)、...
所有任务对象任何一个任务完成就创建一个新的任务并执行 与Task.WhenAny方法 作用相当
微软文档:
Task:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.task?view=netframework-4.8
TaskFactory:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.taskfactory?view=netframework-4.8
C# Task TaskFactory 异步线程/异步任务的更多相关文章
- Filter 快速开始 异步Servlet 异步请求 AsyncContext 异步线程 异步派发 过滤器拦截
[web.xml] <filter> <filter-name>normalFilter</filter-name> <filter-class>net ...
- 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并 ...
- 第四节:Task的启动的四种方式以及Task、TaskFactory的线程等待和线程延续的解决方案
一. 背景 揭秘: 在前面的章节介绍过,Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面 ...
- Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别
Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...
- C#中 Thread,Task,Async/Await 异步编程
什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...
- 用GCD线程组与GCD信号量将异步线程转换为同步线程
有时候我们会碰到这样子的一种情形: 同时获取两个网络请求的数据,但是网络请求是异步的,我们需要获取到两个网络请求的数据之后才能够进行下一步的操作,这个时候,就是线程组与信号量的用武之地了. #impo ...
- net异步线程获取返回值的三种方式
方式一:endInvoke using System; using System.Collections.Generic; using System.Text; using System.Thread ...
- AsyncTask实现异步线程通信
AsyncTask是Android1.5开始提供的一个封装了Thread与Handler可以实现异步线程的简单方式,不需要再自己实现子线程,然后在主线程处接受数据. 因为AsyncTask是用线程池, ...
- Task及Mvc的异步控制器 使用探索
微软的Task已经出来很久了,一直没有去研究,以为就是和Thread差不多的东西.直到最近看到了Task的使用介绍,发现比Thread的语法要精炼多了,于是便在项目中用上了. 结果就出问题了,数据库连 ...
随机推荐
- CCNA 之 十三 广域网概述
广域网概述 为什么需要WAN ? 分区或分支机构的员工需要与总部通信并共享数据: 组织经常需要与其他组织远距离共享信息: 经常出差的员工需要访问公司网络信息: 什么事广域网链路? 用于连接LAN的.跨 ...
- 环境变量PATH、cp命令、mv命令、文档查看cat/more/less/head/tail 各个命令的使用介绍
第2周第2次课(3月27日) 课程内容: 2.10 环境变量PATH2.11 cp命令2.12 mv命令2.13 文档查看cat/more/less/head/tail 2.10 环境变量PATH P ...
- 一个null,差点把系统给弄崩溃了
今天生产上面发现了一个奇异的bug,URL上面会带上一个ID,这个ID是关联别的系统的,类似这种格式 xxx.xxx.xxx.xxx ,是别的系统自己填写的,我们的URL会带上id=xxx.xxx. ...
- 使用PDO连接数据库
PDO(PHP数据对象) 是一个轻量级的.具有兼容接口的PHP数据连接拓展,是一个PHP官方的PECL库,随PHP 5.1发布,需要PHP 5的面向对象支持,因而在更早的版本上无法使用.它所提供的数据 ...
- MyBatis的配置与使用(增,删,改,查)
---恢复内容开始--- Mybatis入门介绍 一.MyBatis介绍 什么是MyBtis? MyBatis 是一个简化和实现了 Java 数据持久化层(persistence layer)的开源框 ...
- “洞察千里”,华为云HiLens如何让无人车智行天下
作者:华为云 Rosie 随着人工智能的普及和渗透,"无人"的场景越来越丰富,无人超市.无人车.无人机等已经融入我们的生活. 乘着这股热浪,华为云携手上海交通大学学生创新中心举办了 ...
- elasticSerach 知识学习
一 介绍: ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java语言开发的, ...
- 利用etcd实现服务注册和服务发现
文章目录 服务注册 服务发现 协议编写 服务端实现 客户端实现 实验结果 参考文章 服务注册 主要逻辑在go func函数里面,先是去etcd获取一下服务,没有获取到的话就注册进去. package ...
- CodeForces-1006B-Polycarp's Practice
B. Polycarp's Practice time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- JS-scrollTop、scrollHeight、clientTop、clientHeight、offsetTop、offsetHeight的理解
scrollTop, 可写(这些属性中唯一一个可写的元素) Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数. 一个元素的 scrollTop 值是这个元素的顶部到 ...