异步多线程(四)Task

2020-12-08 23:49

阅读:511

标签:容器   delay   大于   col   button   span   并发   创建   region   

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 taskList = new List();

taskList.Add(taskFactory.StartNew(() => this.Coding("xxx", "Portal")));

taskFactory.ContinueWhenAny(

taskList.ToArray(),t=>Console.WriteLie()

);

 

ContinueWhenAll

非阻塞式的回调;而且使用的线程可能是新线程,也可能是刚完成任务的线程,唯一不可能是主线程。创建一个延续任务,该任务在一组指定的任务完成后开始

语法:

TaskFactory taskFactory = new TaskFactory();

List taskList = new List();

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 taskList = new List();
            //    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 taskList = new List();
            //    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 taskList = new List();
            //    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 taskList = new List();
            //    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 taskList = new List();
                //实例化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

标签:容器   delay   大于   col   button   span   并发   创建   region   

原文地址:https://www.cnblogs.com/JohnTang/p/10992420.html


评论


亲,登录后才可以留言!