C#中的异步编程(Async)

C#中的异步编程(Async)

前言

所谓的异步,就是指代码在运行的过程中,不会发生阻塞,例如我们玩游戏的时候,游戏在下载资源或者在加载本地资源时,要能够接收UI的输入,如果代码阻塞,表现就是游戏卡死,点了没反应,这个是我们不能接受的,所以异步编程在某些应用场合非常重要,是必不可少的。

在c#中,使用异步编程需要用到Async 、await 等关键字,还需要结合using System.Threading.Tasks下面的Task模板类实现多任务,也就是多个异步操作;当我们调用await 时,虽然会等待任务结束,但是不会发生阻塞;

示例代码

using System;
using System.Threading.Tasks;

namespace AsyncBreakfast
{
    
    
    // These classes are intentionally empty for the purpose of this example. They are simply marker classes for the purpose of demonstration, contain no properties, and serve no other purpose.
    internal class Bacon {
    
     }
    internal class Coffee {
    
     }
    internal class Egg {
    
     }
    internal class Juice {
    
     }
    internal class Toast {
    
     }

    class Program
    {
    
    
        static public long GetTimeStamp()
        {
    
    
            return new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        }

        static async Task Main(string[] args)
        {
    
    
            long time_stamp = 0;
            long end_stamp = 0;
            time_stamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
            Coffee cup = PourCoffee();

            Task<Egg> eggstask = FryEggsAsync(2);  // 这里先将任务存储起来

            Task<Bacon> bacontask = FryBaconAsync(3);

            Task<Toast> toasttask = ToastBreadAsync(2);
			/*
			等待eggstask 返回值,其实在这里,eggstask 、bacontask 、toasttask 是同时执行的,
			只是需要对返回的task值调用await才会有值,相当于就是几个任务同时在执行(猜测C#的异步使用多线程实现的)
			*/
           
            var eggs = await eggstask; // 对eggstask调用await,执行完就会返回值
            Console.WriteLine("eggs are ready");

            var bacon = await bacontask;// 对bacontask调用await,执行完就会返回值
            Console.WriteLine("bacon is ready");

            var toast = await toasttask;// 对toasttask调用await,执行完就会返回值
            ApplyButter(toast);
            ApplyJam(toast);
            Console.WriteLine("toast is ready");

            long end_time = GetTimeStamp();
            Console.WriteLine($"the cost time is {
      
      end_time - time_stamp}");
        }

        private static Juice PourOJ()
        {
    
    
            Console.WriteLine("Pouring orange juice");
            return new Juice();
        }

        private static void ApplyJam(Toast toast) =>
            Console.WriteLine("Putting jam on the toast");

        private static void ApplyButter(Toast toast) =>
            Console.WriteLine("Putting butter on the toast");

        private static async Task<Toast> ToastBreadAsync(int slices)
        {
    
    
        //对于异步的函数实现,是需要有async关键字的,并且返回的类型要用Task泛型,函数里面也必须有
        //await 关键字

            Console.WriteLine("Start toasting...");
            await Task.Delay(3000);
            Console.WriteLine("Remove toast from toaster");
            return new Toast();
        }

        private static async Task<Bacon> FryBaconAsync(int slices)
        {
    
    
            Console.WriteLine($"putting {
      
      slices} slices of bacon in the pan");
            Console.WriteLine("cooking first side of bacon...");
            await Task.Delay(3000);
            Console.WriteLine("cooking the second side of bacon...");
            await Task.Delay(3000);
            Console.WriteLine("Put bacon on plate");

            return new Bacon();
        }

        private static async Task<Egg> FryEggsAsync(int howMany)
        {
    
    
            Console.WriteLine("Warming the egg pan...");
            await Task.Delay(3000);
            await Task.Delay(3000);
            Console.WriteLine("Put eggs on plate");

            return new Egg();
        }

        private static Coffee PourCoffee()
        {
    
    
            return new Coffee();
        }
    }
}

在上述示例代码中,除了可以利用await等待返回值,还可以利用await Task.WhenAll(eggsTask, baconTask, toastTask),实现任务全部完成时,得到一个返回值。

C#官网链接 https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/
对于官网链接中,示例代码的等待时间,文档中给出的是有点问题的,在同步代码中,需要等待的时间是15s,在异步示例代码中,需要等待的时间是6S。
异步和多线程的区别与联系可以看这篇文章: https://blog.csdn.net/qq_41841073/article/details/127785233?spm=1001.2014.3001.5501

猜你喜欢

转载自blog.csdn.net/qq_41841073/article/details/127791670