异步多线程Task
Posted johntang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步多线程Task相关的知识,希望对你有一定的参考价值。
Task
概念:
Task线程是基于线程池的,提供了丰富的API
Task的启动方式
第一种:
Task task = new Task(() => this.DoSomethingLong("btnTask_Click_1"));
task.Start();
第二种:
Task task = Task.Run(() => this.DoSomethingLong("btnTask_Click_2"));
第三种:
TaskFactory taskFactory = Task.Factory;
Task task=taskFactory.StartNew(()=> this.DoSomethingLong("btnTask_Click_3"));
常用API
Delay
Sleep同步等待
Delay异步等待,需要配合ContinueWith()一起使用
Task task = Task.Delay(2000)
.ContinueWith(t =>
stopwatch.Stop();
);//异步等待--等待2s后启动新任务
ContinueWhenAny
非阻塞式的回调;而且使用的线程可能是新线程,也可能是刚完成任务的线程,唯一不可能是主线程。创建一个延续Task,它将在提供的组中的任何任务完成后马上开始
语法:
TaskFactory taskFactory = new TaskFactory();
List<Task> taskList = new List<Task>();
taskList.Add(taskFactory.StartNew(() => this.Coding("xxx", "Portal")));
taskFactory.ContinueWhenAny(
taskList.ToArray(),t=>Console.WriteLie()
);
ContinueWhenAll
非阻塞式的回调;而且使用的线程可能是新线程,也可能是刚完成任务的线程,唯一不可能是主线程。创建一个延续任务,该任务在一组指定的任务完成后开始
语法:
TaskFactory taskFactory = new TaskFactory();
List<Task> taskList = new List<Task>();
taskList.Add(taskFactory.ContinueWhenAll(taskList.ToArray(), rArray => Console.WriteLine()));
WaitAny
阻塞当前线程,等着任意一个任务完成
Task.WaitAny(taskList.ToArray());//也可以限时等待
WaitAll
需要能够等待全部线程完成任务再继续 阻塞当前线程,等着全部任务完成
Task.WaitAll(taskList.ToArray());
ContinueWith
回调,创建一个目标在task完成时异步执行的延续任务
Task.Run(() => this.DoSomethingLong("btnTask_Click"))
.ContinueWith(t => Console.WriteLine());//回调
完整示例代码
#region Task启动 ////Task启动方式一 //Task task = new Task(() => Console.WriteLine("buttonTask_Click")); //task.Start(); ////Task启动方式二 //Task taskRun = Task.Run(() => Console.WriteLine("buttonTask_Click")); ////Task启动方式三 //TaskFactory taskFactory = new TaskFactory(); //Task task2 = taskFactory.StartNew(() => Console.WriteLine("buttonTask_Click")); #endregion #region Delay 异步等待 ////Delay 异步等待 通常是配合ContinueWith()一起使用 ////Sleep同步等待 ////ContinueWhenAny:回调,创建一个目标在task完成时异步执行的延续任务 //Stopwatch stopwatch = new Stopwatch(); ////异步等待,不会阻塞 //Task task = Task.Delay(2000).ContinueWith(t=> // // stopwatch.Stop(); // Console.WriteLine("这是Delay"+"运行时间:"+stopwatch.Elapsed); //); //Console.WriteLine("这是Delay等待之后的方法"); #endregion #region ContinueWhenAny非阻塞的回调 // // //创建一个延续Task,它将在提供的组中的任何任务完成后马上开始 // TaskFactory taskFactory = new TaskFactory(); // List<Task> taskList = new List<Task>(); // taskList.Add(taskFactory.StartNew(() => this.Coding("张三", "ContinueWhenAny 01"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("张四", "ContinueWhenAny 02"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("张五", "ContinueWhenAny 03"))); // taskFactory.ContinueWhenAny(taskList.ToArray(), t => // Console.WriteLine("另外一个方法"); // ); // #endregion #region ContinueWhenAll 非阻塞的回调 // // //创建一个延续Task,它将在提供的组中的所有任务完成后马上开始 // TaskFactory taskFactory = new TaskFactory(); // List<Task> taskList = new List<Task>(); // taskList.Add(taskFactory.StartNew(() => this.Coding("张三", "ContinueWhenAny 01"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("张四", "ContinueWhenAny 02"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("张五", "ContinueWhenAny 03"))); // taskFactory.ContinueWhenAll(taskList.ToArray(), t => // // Console.WriteLine("另外一个方法2"); // ); // #endregion #region WaitAny 阻塞当前线程,等着任意一个任务完成 // // List<Task> taskList = new List<Task>(); // TaskFactory taskFactory = new TaskFactory(); // taskList.Add(taskFactory.StartNew(() => this.Coding("张三", "WaitAny 01"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("李四", "WaitAny 02"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("王五", "WaitAny 03"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("赵六", "WaitAny 04"))); // Task.WaitAny(taskList.ToArray()); // Console.WriteLine("我是另一个方法"); // #endregion #region WaitAll 阻塞当前线程,等着所有任务完成 // // List<Task> taskList = new List<Task>(); // TaskFactory taskFactory = new TaskFactory(); // taskList.Add(taskFactory.StartNew(() => this.Coding("张三", "WaitAny 01"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("李四", "WaitAny 02"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("王五", "WaitAny 03"))); // taskList.Add(taskFactory.StartNew(() => this.Coding("赵六", "WaitAny 04"))); // Task.WaitAll(taskList.ToArray()); // Console.WriteLine("我是另一个方法"); // #endregion #region ContinueWith 创建一个目标在task完成时异步执行的延续任务 // // Task.Run(() => // Console.WriteLine("ContinueWith1"); // Console.WriteLine("ContinueWith11"); // Console.WriteLine("ContinueWith111"); // ).ContinueWith(t=> // Console.WriteLine("ContinueWith2"); // Console.WriteLine("ContinueWith22"); // Console.WriteLine("ContinueWith222"); // ); // #endregion #region 扩展 控制Task的并发数量 //假如说我想控制下Task的并发数量,该怎么做?5个 //准备一个Task容器 List<Task> taskList = new List<Task>(); //实例化TaskFactory TaskFactory taskFactory = new TaskFactory(); taskList.Add(taskFactory.StartNew(() => Console.WriteLine("张三" + "," + "WaitAny 01"))); taskList.Add(taskFactory.StartNew(() => Console.WriteLine("李四" + "," + "WaitAny 02"))); taskList.Add(taskFactory.StartNew(() => Console.WriteLine("王五" + "," + "WaitAny 03"))); taskList.Add(taskFactory.StartNew(() => Console.WriteLine("赵六" + "," + "WaitAny 04"))); for (int i = 0; i < 10; i++) int k = i; //t.Status != TaskStatus.RanToCompletion //如果taskList里不成功的线程数量大于5 if (taskList.Count(t => t.Status != TaskStatus.RanToCompletion) >= 5) 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("00")"); Thread.Sleep(2000); )); #endregion
以上是关于异步多线程Task的主要内容,如果未能解决你的问题,请参考以下文章