链接

超详细: https://www.cnblogs.com/zhaoshujie/p/11082753.html
官方: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task?view=netcore-3.1

基础

ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便。比如:

  • ThreadPool不支持线程的取消、完成、失败通知等交互性操作;
  • ThreadPool不支持线程执行的先后次序;

使用方式:

  1. 函数标记async,则执行这个函数会启用一个线程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static async Task Test()
    {
    await Task.Run(() => {
    // Just loop.
    int ctr = 0;
    for (ctr = 0; ctr <= 1000000; ctr++)
    { }
    Console.WriteLine("Finished {0} loop iterations",
    ctr);
    });

    Console.WriteLine("Finish111");
    }
  2. Task t = Task.Factory.StartNew(action);
  3. Task t = new Task(action);
    t.Start(); //new Task() 默认不会启动 需要主动启动
  4. 父任务包含子任务:关键是父任务中,创建子任务且设置TaskCreationOptions.AttachedToParent
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Task<string[]> parent = new Task<string[]>(state =>
    {
    //创建并启动子任务
    string[] result = new string[2];
    new Task(() => { Thread.Sleep(2000); result[0] = "我是子任务1。"; }, TaskCreationOptions.AttachedToParent).Start();
    return result;
    }
    parent.Start();
    //等待子任务执行完,parent才算执行完成

挂起函数 等待任务完成 注:’t’ 代表Task实例

  1. 等待1个,t.wait();
  2. 等待多个Task,Task.WaitAll(Task[]);
  3. 等待多个Task到其中第一个完成为止,Task.WaitAny(Task[])
  4. Task完成后执行,t.ContinueWith(Action)

Task 接口分析

  1. 取消Task
    设置Task的CancellationToken
    var cts = new CancellationTokenSource();
    cts.Cancel();

  2. 异常处理
    单个任务:
    Try{}
    catch (Exception ex){}
    多个任务:
    Try{}
    Catch(AggregateException ex){}

  3. IProgress异步编程的进程通知
    通过Report传入自定义T值,Progress执行委托

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    static void DoProcessing(IProgress<int> progress)
    {
    for (int i = 0; i <= 100; ++i)
    {
    Thread.Sleep(100);
    if (progress != null)
    {
    progress.Report(i);
    }
    }
    }
    static async Task Display()
    {
    //当前线程
    var progress = new Progress<int>(percent =>
    {
    Console.Clear();
    Console.Write("{0}%", percent);
    });
    //线程池线程
    await Task.Run(() => DoProcessing(progress));
    Console.WriteLine("");
    Console.WriteLine("结束");
    }