zoukankan      html  css  js  c++  java
  • 异步多线程(四)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
  • 相关阅读:
    [NOI2004]cashier 郁闷的出纳员
    [HNOI2004]宠物收养所
    [HNOI2002]营业额统计
    浅谈算法——莫比乌斯反演
    浅谈算法——splay
    [POI2006]Tet-Tetris 3D
    BZOJ2733 [HNOI2012]永无乡 【线段树合并】
    UOJ279 【UTR #2】题目交流通道
    UOJ278 【UTR #2】题目排列顺序
    POJ2761 Feed the dogs
  • 原文地址:https://www.cnblogs.com/JohnTang/p/10992420.html
Copyright © 2011-2022 走看看