C# 学习之 异步编程

主要内容 3种不同模式的异步编程:异步编程、基于事件的异步编程、基于任务的异步编程(TAP)

学习重点 TAP 的关键字 async await

一、异步模式

传统的异步模式可以分为两种,一是,对于一个同步方法如XXX(),其对应的异步模式版本为BeginXXX()和EndXXX()。BeginXXX()接受所有同步方法的输入参数,并且定义了一个AsyncCallback参数,用于在异步方法执行完成后调用委托;EndXXX()使用所有同步方法的输出参数,按照同步方法返回类型返回结果。

二是利用委托的BeginInvoke方法和EndInvoke方法,简单的说从BeginInvoke()调用开始,创建一个新的线程,前台线程继续执行,EndInvoke()会阻塞线程,知道委托的方法执行完毕。

1.两种显示程序运行的方法

    IAsyncResult result =  newTask.BeginInvoke(10000, null, null);
            while (!result.IsCompleted)//方法一
            {
                Thread.Sleep(1000);
                Console.Write("*");
            }
            while (!result.AsyncWaitHandle.WaitOne(100))//方法二
            {
                Console.Write("*");
            }
            int n = newTask.EndInvoke(result);

2.BeginInvoke的输入参数和返回值

参数可以分为两部分,第一部分是调用方法的输入参数,第二部分是回调AsyncCallback,回调方法必须接受一个IAsyncResult参数,接下来的状态参数可以传递委托,从而实现在外部调用EndInvoke()

if (result == null) return;            
            string str1 = (result.AsyncState as MyMethod).EndInvoke(result).ToString();

二、TAP

1.下面的代码说明了同步方法向异步方法的改造

 public static string Greeting(string name)
        {
            Task.Delay(5000).Wait();//Delay也返回一个任务
            return $"Hello,{name}";
        }


        public static Task GreetingAsync(string name)
        {
            return Task.Run(() =>
            {
                return Greeting(name);
            });
        } 

Run要求传递Func委托方法,因为GreetingAsync需要返回Task

2. 注意使用关键字asyncawait ,我的理解是,需要使用await的方法,都需要async,除了特殊的函数,如main;还有一点,await只能修饰返回task的函数;

另外await所在函数里在其后的代码不再执行直到任务完成,因此单独定义一个异步函数,并用async修饰。

private async static void CallerWithAsync()
        {
            string result = await GreetingAsync("huangxianxiang");
            WriteLine(result);
        }

3.await延续任务 下面代码可以看出await后面应该避免使用ui元素,避免切换到同步上下文会执行的更快

private static void CallerWithContinuousTask()
        {
            Task t1 = GreetingAsync("huangxianxiang");
            t1.ContinueWith(t =>
            {
                string result = t.Result;
                WriteLine(result);
            });
        }
4.组合器

Task s1 = GreetingAsync("sunyan");
            Task s2 = GreetingAsync("huangxianxiang");
            string[] strList = await Task.WhenAll(s1, s2);

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