欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Async和Await的异步编程

程序员文章站 2022-04-30 20:37:26
...

使用Async和Await的异步编程

遇到await后,后序代码由新线程接管,即操作开始异步。
官方文档

简易版

使用Async和Await的异步编程

不阻塞主线程

使用Async和Await的异步编程

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}:{SayAsync().Status}");
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            Console.ReadKey(true);
        }

        public static async Task<string> SayAsync()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}_SayAsync");

            var s = await Task<string>.Run(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(2));
                Console.WriteLine("---------------两秒后----------------");
                Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}");
                return "vvull";
            });
            Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}:{s}");
            Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}");
            return s;
        }

    }

阻塞主线程

使用Async和Await的异步编程

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}:{SayAsync().Result}");//阻塞主线程
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}");
            Console.ReadKey(true);
        }

        public static async Task<string> SayAsync()
        {
            Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}_SayAsync");

            var s = await Task<string>.Run(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(2));
                Console.WriteLine("---------------两秒后----------------");
                Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}");
                return "vvull";
            });
            Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}:{s}");
            Console.WriteLine($"子线程{Thread.CurrentThread.ManagedThreadId}");
            return s;
        }

    }

进阶版

使用Async和Await的异步编程

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->主线程");
            giaoAsync();
            Thread.Sleep(3000);
            Console.WriteLine("---------------三秒后----------------");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->主线程");
            Console.ReadKey();
        }
        static async Task giaoAsync()
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao");

            //Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao:{await SayAsync()}");//本句以后由新线程接管
            //Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao*");

            var s = await SayAsync();//由新线程接管
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao**_{s}");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao**");

            var ss = await SayAsync();//由新线程接管
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao***_{ss}");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->giao***");
        }

        public static async Task<string> SayAsync()
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync");

            var s = await Task<string>.Run(async () =>
            {                
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync*");
                await Task.Delay(TimeSpan.FromSeconds(2));
                Console.WriteLine("---------------两秒后----------------");
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**");
                return "vvull";
            });
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**_{s}");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->SayAsync**");
            return s;
        }

    }

官方例子魔改

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncBreakfast
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Coffee cup = PourCoffee();
            Console.WriteLine("coffee is ready");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            var eggsTask = FryEggsAsync(2);
            var baconTask = FryBaconAsync(3);
            var toastTask = MakeToastWithButterAndJamAsync(2);
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            var breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask };
            while (breakfastTasks.Count > 0)
            {
                Task finishedTask = await Task.WhenAny(breakfastTasks);
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程**");
                if (finishedTask == eggsTask)
                {
                    Console.WriteLine("eggs are ready");
                }
                else if (finishedTask == baconTask)
                {
                    Console.WriteLine("bacon is ready");
                }
                else if (finishedTask == toastTask)
                {
                    Console.WriteLine("toast is ready");
                }
                breakfastTasks.Remove(finishedTask);
                Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程**");
            }
            Juice oj = PourOJ();
            Console.WriteLine("oj is ready");
            Console.WriteLine("Breakfast is ready!");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程***");
            Console.ReadKey();
        }

        static async Task<Toast> MakeToastWithButterAndJamAsync(int number)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            var toast = await ToastBreadAsync(number);
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程");
            ApplyButter(toast);
            ApplyJam(toast);

            return toast;
        }

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

        private static void ApplyJam(Toast toast) =>
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程   " + "Putting jam on the toast");

        private static void ApplyButter(Toast toast) =>
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程   " + "Putting butter on the toast");

        private static async Task<Toast> ToastBreadAsync(int slices)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            for (int slice = 0; slice < slices; slice++)
            {
                Console.WriteLine("Putting a slice of bread in the toaster");
            }
            Console.WriteLine("Start toasting...");
            await Task.Delay(3000);
            Console.WriteLine("--------Toast三秒后--------");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Toast线程");
            Console.WriteLine("Remove toast from toaster");

            return new Toast();
        }

        private static async Task<Bacon> FryBaconAsync(int slices)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            Console.WriteLine($"putting {slices} slices of bacon in the pan");
            Console.WriteLine("cooking first side of bacon...");
            await Task.Delay(3000);
            Console.WriteLine("--------Bacon三秒后--------");
            for (int slice = 0; slice < slices; slice++)
            {
                Console.WriteLine("flipping a slice of bacon");
            }
            Console.WriteLine("cooking the second side of bacon...");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Bacon线程*");
            await Task.Delay(3000);
            Console.WriteLine("--------Bacon第二次三秒后--------");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Bacon线程**");
            Console.WriteLine("Put bacon on plate");

            return new Bacon();
        }

        private static async Task<Egg> FryEggsAsync(int howMany)
        {
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->线程*");
            Console.WriteLine("Warming the egg pan...");
            await Task.Delay(3000);
            Console.WriteLine("--------Eggs三秒后--------");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Eggs线程*");
            Console.WriteLine($"cracking {howMany} eggs");
            Console.WriteLine("cooking the eggs ...");
            await Task.Delay(3000);
            Console.WriteLine("--------Eggs第二次三秒后--------");
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}->Eggs线程**");
            Console.WriteLine("Put eggs on plate");

            return new Egg();
        }

        private static Coffee PourCoffee()
        {
            Console.WriteLine("Pouring coffee");
            return new Coffee();
        }
    }

    class Egg
    {

    }

    class Toast
    {

    }

    class Juice
    {

    }

    class Bacon
    {

    }

    class Coffee
    {

    }
}