关于C#异步编程的代码笔记

异步学习代码笔记

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

namespace ConsoleApp7
{
    class Program
    {
        [STAThread]
        static void  Main(string[] args)//三个方法如果同步执行需要16s,而采用异步方式不仅主线程不会被阻塞,执行完也只需要10s,因为他们是并行执行的
        {
            Console.WriteLine("Main_" + Thread.CurrentThread.ManagedThreadId);
            Coffee cup = PourCoffee();
            Console.WriteLine("coffee is ready_"+DateTime.Now);
            Task eggs = FryEggs(2);//1s
            Console.WriteLine("eggs are ready_"+DateTime.Now);
            Task bacon =  FryBacon(3);//5s
            Console.WriteLine("bacon is ready_" + DateTime.Now);
            Task toast = ToastBreadAsync1(2);//10s
            Toast result1 = toast.Result;
            Bacon result2 = bacon.Result;
            Egg resul3 = eggs.Result;
            Console.WriteLine("toast is ready_" + DateTime.Now);
            Juice oj = PourOJ();
            Console.WriteLine("oj is ready");
            Console.WriteLine("Breakfast is ready!");
            Console.ReadLine();
        }


   public  static async Task HHAsync()//此方法只有async而没有await,因此该方法为同步方法,区别是返回的                     //t.Result类型为Toast,而方法的返回则是Task
        {
            var t=    ToastBreadAsync1(1);//async可以单独使用,await必须和async配合使用
            return t.Result;
        }
        
        private static Juice PourOJ()
        {
            return new Juice();
        }

        private async static Task ToastBreadAsync1(int v)//需要依赖返回值进行进一步的处理则需要封装成async异步方法,以便await结果进行后续处理
        {
            Toast toast = await ToastBread(v);
            ApplyButter(toast);//相当于回调的代码
            ApplyJam(toast);//相当于回调的代码
            return toast;
        }
        private static Task ToastBread(int v)//供ToastBreadAsync1封装成异步方法
        {
            return  Task.Factory.StartNew(()=> { Thread.Sleep(1000); Console.WriteLine("Toast_" + Thread.CurrentThread.ManagedThreadId); return new Toast(); });
        }

        private static Task FryBacon(int v)//如果无需关心返回值则调用方直接调用任务方法而无需封装成async异步方法
        {
            return Task.Factory.StartNew(() => { Thread.Sleep(5000); Console.WriteLine("Bacon_"+Thread.CurrentThread.ManagedThreadId); return new Bacon(); });
        }

        private static Task FryEggs(int v)//如果无需关心返回值则调用方直接调用任务方法而无需封装成async异步方法
        {
            return  Task.Factory.StartNew(() => { Thread.Sleep(10000);Console.WriteLine("Eggs_"+Thread.CurrentThread.ManagedThreadId); return new Egg(); });
        }

        private static void ApplyJam(Toast toast)//类似回调的方法
        {
            Thread.Sleep(3000);
            Console.WriteLine("ApplyJam finished_" + DateTime.Now);
        }

        private static void ApplyButter(Toast toast)//类似回调的方法
        {
            Thread.Sleep(3000);
            Console.WriteLine("ApplyButter finished_" + DateTime.Now);
        }

    

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

    internal class Toast
    {
    }

    internal class Coffee
    {
    }

    //要点1:创建Task除了可以用new+手动start,还可以通过Task.Factory.StartNew()实现;
    //要点2:如上带有返回值的异步方法ToastBreadAsync1的返回值与return的值类型是不一样的。
    //且其返回的Task为其包含内部两个同步方法ApplyButter/ApplyJam的Task,
    //而不单纯是 await ToastBread(v)返回的Task
    //要点3:当调用异步方法的Task.Result时会阻塞线程。调用Task.wait()显式阻塞线程.
    //在web开发中假设需要调用多个接口获取返回值合并输出到web页面时的场景会用到线程阻塞。
}

你可能感兴趣的:(C#)