【多线程】Task
介绍
Task是.NET推出数据任务处理的工作类。位于System.Threading.Tasks命名空间下,通过命名空间也可以看出是个多线程类。
创建Task:
Task有很多构造函数,无参有参都有,想了解更多可以去官网查看。这里只介绍经常用的形式。
第一种:以类的实例化形式进行创建Task。通过实例化一个Task对象,然后Start,这种方式中规中矩。
Task Task1 = new Task(() => Console.WriteLine("Task"));
Task1.Start();
第二种:在实践中通常使用这种简洁形式,这种直接运行了Task不需要在start调用
Task.Run(() => Console.WriteLine("Task"));
第三种:通过Task的静态属性创建,然后直接启动。Factory提供对用于创建 Task 和 Task<TResult> 的工厂方法的访问。
var t1= Task.Factory.StartNew(() =>
{
Console.WriteLine("Task");
});
StartNew和Run区别
这两个应用的场景都是一样的,只不过Run是StartNew的再次封装吧,与之相比Run比StartNew自动执行了Unwrap。
Unwrap:主要的作用就是会把嵌套在Task或者Task<>的结果提取出来。
判断执行状态:
通过IsCompleted属性可以查看当前task是否执行完成。
var t11 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task");
});
if (t11.IsCompleted)
{
Console.WriteLine("线程已经完成");
}
等待控制:
通过WhenAny和WhenAll来控制等待,WhenAny表示任意一个Task完成之后,返回这个Task对象,但是有时候我们需要等待任务的完成,WhenAll表示处理完成之后,返回所有对象实例。例如:
List<Task<string>> TaskList = new List<Task<string>>() {
Task.Factory.StartNew(()=> { return WriteHello(); },C1.Token),
Task.Factory.StartNew(()=> { return WriteHello(); },C1.Token),
Task.Factory.StartNew(()=> { return WriteHello(); },C1.Token),
Task.Factory.StartNew(()=> { return WriteHello(); },C1.Token)
};
//var Reuslt= await Task.WhenAll(TaskList);
var Reuslt = await Task.WhenAny(TaskList);
if (Reuslt.IsCompleted)
{
Console.WriteLine("有人完成了");
}
等待的时候,要加上async 和 await;
以上是异步等待,要想实现同步操作使用AwaitAll
var t1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task1");
});
var t2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task2");
});
var t3 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task3");
}); //等待并行完成
Task.WaitAll(t1, t2, t2, t3);
此时只有执行完成所有task后才会执行下面的代码。
死锁问题
此代码仅作保存研究
出现死锁:
#region 并行死锁问题
public static void ParallelLock()
{
var t1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 1 Start running...");
while (true)
{
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Task 1 Finished!");
});
var t2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 2 Start running...");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 2 Finished!");
});
Task.WaitAll(t1, t2);
}
#endregion
解决办法:
#region 解决死锁问题
/// <summary>
/// 解决死锁问题设置时间
/// </summary>
public static void ParallelLockEnd()
{
Task[] tasks = new Task[];
tasks[] = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 1 Start running...");
while (true)
{
System.Threading.Thread.Sleep();
}
Console.WriteLine("Task 1 Finished!");
});
tasks[] = Task.Factory.StartNew(() =>
{
Console.WriteLine("Task 2 Start running...");
System.Threading.Thread.Sleep();
Console.WriteLine("Task 2 Finished!");
}); Task.WaitAll(tasks, );
for (int i = ; i < tasks.Length; i++)
{
if (tasks[i].Status != TaskStatus.RanToCompletion)
{
Console.WriteLine("Task {0} Error!", i + );
}
}
Console.Read();
}
#endregion
【多线程】Task的更多相关文章
- .Net进阶系列(13)-异步多线程(Task和Parallel)(被替换)
一. Task开启多线程的三种形式 1. 利用TaskFactory下的StartNew方法,向StartNew传递无参数的委托,或者是Action<object>委托. 2. 利用Tas ...
- 多线程Task
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- C# 多线程task
1.异步和多线程的区别?没什么太大区别.异步是目的,使用多线程实现.想想AJAX异步加载,不就是不想让浏览器界面卡住嘛,所以在程序中对于某些单独的操作,比如写日志,我们不想等它完成后再执行其它操作(因 ...
- 多线程--Task,等待用户输入AutoResetEvent
上一篇文章:.NET:如何让线程支持超时?已经说明目前微软主推的多线程方案是task: 注意:Task最好引用.NET4.5. 4.0也行,但不成熟.Thread引用2.0就够了. 1.通过构造函数创 ...
- [.net 多线程]Task
C# 异步编程Task整理(一) c# .Net并行和多线程编程之Task学习记录! .NET 实现并行的几种方式(一) Dispatcher介绍 [C#学习笔记]使用C#中的Dispatcher 用 ...
- 多线程-Task、await/async
Task创建无返回值 Task是.netframwork4.0重新分装的多线程类.原因以前的多线程(thread threadpool)不好用.(.net framwork也是的发展的,现在的EF,刚 ...
- 线程——自定义多线程task
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 异步多线程 Task理解
一.简介 Task是.NET Framework4.0 TPL(任务并行库)提供的新的操作线程池线程的封装类.它提供等待.终止(取消).返回值.完成通知.失败通知.控制执行的先后次序等优化线程操作功能 ...
- C#多线程---Task实现异步
一.场景 使用Task来进行累加操作. 二.例子-Task使用 1 using System; 2 using System.Collections.Generic; 3 using System.L ...
- .Net 多线程 异步编程 Await、Async和Task
await和async简介 await和async是在C#5中引入,并且在.NetFramewor4.5以及.NetCore中进行了支持.主要是解决性能瓶颈,并且增强系统的响应能力. msdn关于 ...
随机推荐
- 第一节20181109 《Linux就该这么学》
在网上发现了刘老师的linux课程,关注了一段时间感觉很好就在10月1日活动日报了第19期的班,希望自己能坚持下来学好linux.
- “全栈2019”Java多线程第三十七章:如何让等待的线程无法被中断
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 了解Java基本数据类型的取值范围
拿byte类型做栗子 一个字节是8位二进制数,然后最高位会用来作为符号位.正数计算机是存的原码,负数是存的补码. 也就说byte正数最大是0111 1111,转化为十进制是:127(这就是byte的上 ...
- Akka-Cluster(0)- 分布式应用开发的一些想法
当我初接触akka-cluster的时候,我有一个梦想,希望能充分利用actor自由分布.独立运行的特性实现某种分布式程序.这种程序的计算任务可以进行人为的分割后再把细分的任务分派给分布在多个服务器上 ...
- VMware Tools安装教程
安装依赖: sudo yum install eject 步骤: 确保 Linux 虚拟机已打开电源. 如果正在运行 GUI 界面,请打开命令 shell. 注意:以 root 用户身份登录,或使用 ...
- go操作redis
package main import ( "fmt" "github.com/gomodule/redigo/redis" ) func main() { c ...
- Swift5 语言指南(十七) 反初始化
一个deinitializer一个类的实例被释放之前立即调用.您使用deinit关键字编写deinitializers ,类似于使用init关键字编写初始化程序的方式.Deinitializers仅适 ...
- SQLServer 查看耗时较多的SQL语句(转)
total_worker_time AS [总消耗CPU 时间(ms)],execution_count [运行次数], qs.total_worker_time AS [平均消耗CPU 时间(ms) ...
- SSM工作流程的大致理解
//不是根据源码来理解的,所以细节有省略.. 首先从在浏览器输入URl的那一刻开始 例如输入 localhost:8080/MyProject/listCategory 初始化: 此时tomcat已经 ...
- VS发布 错误 未能将文件 复制到
在VS内部编译及试运行的时候并为出现错误一切正常 当将项目发布时提示XXX文件无法复制到对应的obj文件夹下 未能将文件 upfile\team\2013\0328\20130328112637296 ...