zoukankan      html  css  js  c++  java
  • C#Task和async/await使用

    一:什么是异步

    当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。

      异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、较耗时的任务设为异步执行,可以提高程序的运行效率。net4.0在ThreadPool的基础上推出了Task类,微软极力推荐使用Task来执行异步任务,现在C#类库中的异步方法基本都用到了Task;net5.0推出了async/await,让异步编程更为方便。本篇主要介绍Task、async/await相关的内容。

    二:Task介绍

    ThreadPool不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知。net4.0在ThreadPool的基础上推出了Task,Task拥有线程池的优点,同时也解决了使用线程池不易控制的弊端。

    1、Task创建与运行

     1.1 创建task三种方式

    Task task = new Task(() =>
                {
                    Console.WriteLine("第一个任务!");
                });
                task.Start();
                Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("第二个任务");
                });
                Task.Run(() =>
                {
                    Console.WriteLine("第三个任务");
                });
                Console.WriteLine("执行主线程!");

     运行结果:

    1.2 带返回值的Task

    var task = new Task<string>(() =>
                {
                    return "第一个任务";
                });
                task.Start();
                var task2 = Task<string>.Factory.StartNew(() =>
                  {
                      return "第二个任务";
                  }).Result;
                var task3 = Task<string>.Run<string>(() =>
                  {
                      return "第三个任务";
                  }).Result;
                Console.WriteLine(task.Result);
                Console.WriteLine(task2);
                Console.WriteLine(task3);
                Console.WriteLine("执行主线程!");
                Console.ReadKey();

    运行结果:

     1.3 Task同步执行

    Task task = new Task(() =>
    {
    Console.WriteLine("第一个任务!");
    });
    task.RunSynchronously();

    2、Task的阻塞方法(Wait/WaitAll/WaitAny)

    task.Wait()、task2.Wait()和Task.WaitAll(task,task2)意义相同

    Task.WaitAny(task,task2)执行完任何一个即可执行下面代码

    Task task = new Task(() =>
                {
                    Console.WriteLine("第一个任务!");
                });
                task.Start();
                Task task2 = new Task(() =>
                {
                    Console.WriteLine("第二个任务!");
                });
                task2.Start();
                //task.Wait();
                //task2.Wait();
                Task.WaitAny(task,task2);
                //Task.WaitAll(task, task2);

     3 Task的延续操作(WhenAny/WhenAll/ContinueWith)

    WhenAll等待所有任务完成执行延续的操作
    WhenAny等待某个任务完成执行延续的操作

    ContinueWith延续执行
    Task task = new Task(() =>
                {
                    Console.WriteLine("第一个任务!");
                });
                task.Start();
                Task task2 = new Task(() =>
                {
                    Console.WriteLine("第二个任务!");
                });
                task2.Start();
                Task.WhenAny(task, task2).ContinueWith((t) =>
                {
                    Console.WriteLine("延续后执行!");
                });
                //Task.WhenAll(task, task2).ContinueWith((t) =>
                //{
                //    Console.WriteLine("延续后执行!");
                //});
                Console.WriteLine("执行主线程!");
                Console.ReadKey();

    3、Task的任务取消(CancellationTokenSource)

    CancellationTokenSource source = new CancellationTokenSource();
                //注册任务取消的事件
                source.Token.Register(() =>
                {
                    Console.WriteLine("任务被取消后执行!");
                });
    
                int index = 0;
                //开启一个task执行任务
                Task task1 = new Task(() =>
                {
                    while (!source.IsCancellationRequested)
                    {
                        Thread.Sleep(1000);
                        Console.WriteLine($"第{++index}次执行,线程运行中...");
                    }
                });
                task1.Start();
                //延时取消,效果等同于Thread.Sleep(5000);source.Cancel();
                source.CancelAfter(5000);
                Console.ReadKey();

    三:异步方法

    static void Main(string[] args)
    {
        var name = GetNameAsync().GetAwaiter().GetResult();
                SaveInfoAsync().GetAwaiter().GetResult();
                Console.WriteLine(name);
    }
    /// <summary>
    /// 异步带返回值
    /// </summary>
    /// <returns></returns>   
    static async Task<string> GetNameAsync()
    {
                return "wuzhd";
    }
    /// <summary>
    /// 异步无返回值
    /// </summary>
    /// <returns></returns>
    static async Task SaveInfoAsync()
    {
    
    }
  • 相关阅读:
    变形金刚还有一个星期!
    SQLSERVER中日期显示样式(网络收集)
    美国《商业周刊》网站提前公布的2007年度世界最有价值品牌
    昨天论文被录 开心
    怎样用javascript操作ftb编辑区内容
    c#中 @的用处
    图片滚动代码。
    一段实现分页的存储过程
    下拉列表控制文本框的个数思路
    什么是ERP (转载自百度知道)
  • 原文地址:https://www.cnblogs.com/ZhengHengWU/p/12988785.html
Copyright © 2011-2022 走看看