zoukankan      html  css  js  c++  java
  • 异步编程,await async入门

    网上很多异步编程的文章,提供一篇入门:

    异步编程模型

    .net支持3种异步编程模式:

     msdn:https://docs.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/

    推荐大家先看我写的,再针对各个部分查看msdn的详细内容

    1、  异步编程模型 (APM:Asynchronous Programming Model)

    使用 IAsyncResult 设计模式的异步操作是通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现的,这两个方法分别开始和结束异步操作 OperationName

    开始异步操作

    BeginOperationName 方法开始异步操作 OperationName,并返回实现 IAsyncResult 接口的对象。 IAsyncResult 对象存储有关异步操作的信息。

    结束异步操作

    EndOperationName 方法用于结束异步操作 OperationName。 EndOperationName 方法的返回值与其同步对应方法的返回值类型相同,并且是特定于异步操作的。

     

    在msdn上是以文件读取作为例子。这里以更简单的例子进行演示。如果可以进行单元测试的,可直接在单元测试中进行,没有的则可以使用控制台应用程序进行。

    委托对象有以BeginInvoke和EndInvoke,所以使用委托进行演示:

     

    1.1要被调用的方法:这是一个带有参数且有字符串返回值的方法

     1 static string ShowInfo(string info)
     2 
     3  {
     4 
     5      Console.WriteLine("方法调用"+info);
     6 
     7      int result = 0;
     8 
     9      for (int i = 1; i < 100; i++)
    10 
    11      {
    12 
    13          result += i;
    14 
    15          System.Threading.Thread.Sleep(10);
    16 
    17      }
    18 
    19      return result.ToString();
    20 
    21  }

    以上方法,一个输入,一个输出,都是字串,方法体中会打印方法调用字样,并打印输入字串。然后计算1到99的数字的和值,其中每次数字输出会休眠10毫秒。最后返回和值。

    以上仅为演示和模拟算法效果。

     

    1.2

     

     1 //委托对象
     2 
     3 static SayHi xx = new SayHi(ShowInfo);
     4 
     5 static void Main(string[] args)
     6 
     7 {
     8 
     9     //回调委托对象
    10 
    11     AsyncCallback callback = new AsyncCallback(show);
    12 
    13     //异步开始
    14 
    15     var ret=xx.BeginInvoke("", null, null);
    16 
    17     string result = xx.EndInvoke(ret);
    18 
    19     Console.WriteLine(result);
    20 
    21      Console.Read();
    22 
    23 }

     

    以上方法,先定义了一个与1.1中方法ShowInfo方法匹配的委托:即此委托对象可以apm异步调用,即异步调用 ShowInfo方法。

    在BeginInvoke时,第二个参数,即回调方法设置为null,即不使用回调方法。

    BeginInvoke方法如下:

    public IAsyncResult BeginInvoke (

        InvokeArgs invokeArgs,

        AsyncCallback callback,

        Object userState

    )

    第一个参数是委托方法的参数:ShowInfo方法的输入参数

    第二个参数是回调方法:完成调用ShowInfo方法后要执行的动作,这里是个(回调)方法

    第三个参数是操作关联的可选状态

     

    EndInvoke方法如下:

    public InvokeCompletedResult EndInvoke (

        IAsyncResult asyncResult

    )

    参数是 BeginInvoke方法的返回值。而返回值是InvokeCompletedResult类型,委托对象的返回值,即方法ShowInfo的返回值。

     

    BeginInvoke方法的返回值为IAsyncResult类型。第二个参数为AsyncCallback类型。

    AsyncCallback是一个委托类型,查看它的定义是这样的:

    public delegate void AsyncCallback(IAsyncResult ar);

    它是一个无返回值参数是IAsyncResult类型的委托。所以回调方法签名与与这相符,定义回调方法如下:

    //回调方法
    
     static void show(IAsyncResult asr)
    
     {
    
         string result = xx.EndInvoke(asr);
    
         Console.WriteLine(result);
    
         Console.WriteLine("结束");
    
     }

      

    2、  基于事件的异步模式 (EAP)

     

     未完待

     

    3、  基于任务的异步模式 (TAP)

    与之离不开的是Task类。它的构造方法如下:

     

     即,接收action委托。

    最简单的调用如下:

     1 static void Main(string[] args)
     2 
     3   {
     4 
     5       Action act=delegate()
     6 
     7       {
     8 
     9           Console.WriteLine("方法打印信息");
    10 
    11       };
    12 
    13       Task t = new Task(act);
    14 
    15       t.Start();
    16 
    17       Console.Read();
    18 
    19   }

    通过匿名方法,lambda可以省略为:

     1 static void Main(string[] args)
     2 
     3  {
     4 
     5      //Action act=delegate()
     6 
     7      //{
     8 
     9      //    Console.WriteLine("方法打印信息");
    10 
    11      //};
    12 
    13      Task t = new Task(()=>{
    14 
    15          Console.WriteLine("方法打印信息");
    16 
    17      });
    18 
    19      t.Start();
    20 
    21      Console.Read();
    22 
    23  }

    此外,可以通过Task的静态工厂创建任务,如下:

     

     1 Task t = Task.Factory.StartNew(
     2 
     3                 () => {
     4 
     5                     Console.WriteLine("方法打印信息");
     6 
     7                 }
     8 
     9                 );
    10 
    11             t.Start();
    12 
    13             Console.Read();

    总之,效果是一样的。

    以下代码用于演示同步:

     1 static void Main(string[] args)
     2 
     3   {
     4 
     5       Console.WriteLine(1);
     6 
     7       Console.WriteLine(2);
     8 
     9       Task taskA = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine(3); });
    10 
    11       try
    12 
    13       {
    14 
    15           taskA.Wait();
    16 
    17           Console.WriteLine(4);
    18 
    19       }
    20 
    21       catch (AggregateException)
    22 
    23       {
    24 
    25           Console.WriteLine("Exception in taskA.");
    26 
    27       }
    28 
    29       Console.WriteLine(5);
    30 
    31       Console.Read();
    32 
    33   }

     

    首先main输出 1和2,然后此时插入任务taskA。它在休眠2秒后,输出3,然后任务结束后输出4,最后main中输出5。

    任务taskA执行完毕后大概需要2秒钟的时间,这样,如果不等待taskA,即taskA启动执行后,不等待执行完毕,则会执行输出  4和5。

    最终打印结果是:1,2,4,5,3(顺序是这样的,但格式是带回车的)

    如果进行等待,Wait() 不带参数,表示一直等待到任务执行完毕。

    这样,就可以按顺序输出了,最终结果是:1,2,3,4,5

    同样的Task类有对应的泛型类型,这里不演示了。

     

    await

    msdn: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/await

     

    await运算符用于异步方法中的任务,在方法的执行中插入挂起点,直到所等待的任务完成。仅可用于由async关键字修改的异步方法中。

    应用await运算符的任务通常由实现基于任务的异步模式的方法调用返回。包括:Task,Task<TResult>,ValueTask 和ValueTask<TResult> 对象的方法。

     

    async

    msdn: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/async

     

    async修饰符可将方法、lambda表达式,匿名方法指定为异步,带此修饰符的方法或表达式称为异步方法。

     

    Msdn上一个非常好的例子:它是有顺序的执行任务,这样通过await达到同步的结果,

    https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/index

  • 相关阅读:
    深度学习中Embedding的理解
    Chrome 历史版本下载点
    [Angular] Inherit Parent Route Parameters by Default with ParamsInheritanceStrategy
    [Web] Use Web Speech API to make the browser speak out loud using SpeechSynthesis
    [React] useImperativeHandle + forwardRef
    [XState] Assignement actions
    [XState] Using global actions prop for testing
    [ML L9] Clustering (K-MEANS)
    html+php超大视频上传解决方案
    上传大型视频文件到服务器的分享
  • 原文地址:https://www.cnblogs.com/jams742003/p/11095717.html
Copyright © 2011-2022 走看看