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

异步编程模型

.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要被调用的方法:这是一个带有参数且有字符串返回值的方法

 static string ShowInfo(string info)

  {

      Console.WriteLine("方法调用"+info);

      int result = ;

      for (int i = ; i < ; i++)

      {

          result += i;

          System.Threading.Thread.Sleep();

      }

      return result.ToString();

  }

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

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

1.2

 //委托对象

 static SayHi xx = new SayHi(ShowInfo);

 static void Main(string[] args)

 {

     //回调委托对象

     AsyncCallback callback = new AsyncCallback(show);

     //异步开始

     var ret=xx.BeginInvoke("", null, null);

     string result = xx.EndInvoke(ret);

     Console.WriteLine(result);

      Console.Read();

 }

以上方法,先定义了一个与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委托。

最简单的调用如下:

 static void Main(string[] args)

   {

       Action act=delegate()

       {

           Console.WriteLine("方法打印信息");

       };

       Task t = new Task(act);

       t.Start();

       Console.Read();

   }

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

 static void Main(string[] args)

  {

      //Action act=delegate()

      //{

      //    Console.WriteLine("方法打印信息");

      //};

      Task t = new Task(()=>{

          Console.WriteLine("方法打印信息");

      });

      t.Start();

      Console.Read();

  }

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

 Task t = Task.Factory.StartNew(

                 () => {

                     Console.WriteLine("方法打印信息");

                 }

                 );

             t.Start();

             Console.Read();

总之,效果是一样的。

以下代码用于演示同步:

 static void Main(string[] args)

   {

       Console.WriteLine();

       Console.WriteLine();

       Task taskA = Task.Run(() => { Thread.Sleep(); Console.WriteLine(); });

       try

       {

           taskA.Wait();

           Console.WriteLine();

       }

       catch (AggregateException)

       {

           Console.WriteLine("Exception in taskA.");

       }

       Console.WriteLine();

       Console.Read();

   }

首先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

异步编程,await async入门的更多相关文章

  1. .Net 4.5 异步编程初试(async和await)

    .Net 4.5 异步编程初试(async和await) 前言 最近自己在研究Asp.Net Web API.在看到通过客户端来调用Web API的时候,看到了其中的异步编程,由于自己之前没有接触过, ...

  2. 异步编程(Async和Await)的使用

    .net4.5新特性之异步编程(Async和Await)的使用 一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个“主题”.即:C#1.0托管代码→C#2. ...

  3. .Net异步编程详解入门

    前言 今天周五,早上起床晚了.赶着挤公交上班.但是目前眼前有这么几件事情.刷牙洗脸.泡牛奶.煎蛋.在同步编程眼中.先刷牙洗脸,然后烧水泡牛奶.再煎蛋,最后喝牛奶吃蛋.毫无疑问,在时间紧促的当下.它完了 ...

  4. .NET4.5新特性之异步编程(Async和Await)的使用

    一.简介 首先来看看.net的发展中的各个阶段的特性:NET 与C# 的每个版本发布都是有一个"主题".即:C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语 ...

  5. 多线程之异步编程: 经典和最新的异步编程模型,async与await

    经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...

  6. .NET异步编程初识async与await

    这是两个关键字,用于异步编程.我们传统的异步编程方式一般是Thread.ThreadPool.BeginXXX.EndXXX等等.把调用.回调分开来,代码的逻辑是有跳跃的,于是会导致思路不是很清晰的问 ...

  7. 《C#并发编程经典实例》学习笔记—异步编程关键字 Async和Await

    C# 5.0 推出async和await,最早是.NET Framework 4.5引入,可以在Visual Studio 2012使用.在此之前的异步编程实现难度较高,async使异步编程的实现变得 ...

  8. C# 异步编程4 async与await 异步程序开发

    随着C#异步程序开发系列的深入,你会发现编写异步程序越发简单.事物的发展就是这样的规律,从简单到复杂再到简单. 在C# 5.0中我们可以通过async与await关键字实现快捷的异步程序开发,如下: ...

  9. C#异步编程のawait和async关键字来写异步程序

    一.await和async关键字 .Net平台不断推出了新的异步编程模型,在.net4.5中加入了关键字await和async,顾名思义,await是指方法执行可等待,即可挂起直到有结果(不是必须立即 ...

随机推荐

  1. SQL SERVER 数据库授权指定用户

    在查询分析器下运行以下语句即可: GO USE [master] GO ALTER AUTHORIZATION ON DATABASE::[数据库名] TO [用户名] GO

  2. JQ中的Ajax的封装

    1.认识JQ中ajax的封装      jQ 对于ajax的封装有两层实现:$.ajax 为底层封装实现:基于 $.ajax ,分别实现了$.get 与$.post 的高层封装实现: 2.Ajax的底 ...

  3. 通过SSH通道来访问MySQL

     许多时候当要使用Mysql时,会遇到如下情况: 1. 信息比较重要,希望通信被加密.2. 一些端口,比如3306端口,被路由器禁用. 对第一个问题的一个比较直接的解决办法就是更改mysql的代码,或 ...

  4. Java生鲜电商平台-优惠券系统的架构设计与源码解析

    Java生鲜电商平台-优惠券系统的架构设计与源码解析 电商后台:实例解读促销系统 电商后台系统包括商品管理系统.采购系统.仓储系统.订单系统.促销系统.维权系统.财务系统.会员系统.权限系统等,各系统 ...

  5. java核心技术第六篇之断言、日志、包装类型和工具类

    JDK1.5新特性: 1.自动拆装箱. 2.泛型 3.可变参数 4.静态导入 5.增强for循环 6.互斥锁 7.枚举 8.注解 JDK1.6新特性: 1.Desktop类和SystemTray类 2 ...

  6. 在Vue-cli3.x中引入element-ui的新方式

    今天登上element官网,发现element对vue-cli3.x的项目做了特殊定制: 这意味着即使是按需引入,也无需像过去那样手动安装babel-plugin-component,配置babel. ...

  7. STM32 IAP 升级功能

    IAP In Application Programming 可通过USB,CAN,UART,I2C,SPI等接口实现 IAP流程 Bootloader程序:接收升级程序,更新到flash指定地址:跳 ...

  8. curl ftp libcurl 功能使用

    struct FtpFile { const char *filename; FILE *stream; }; static size_t my_fwrite(void *buffer, size_t ...

  9. 上传App Store 被拒问题及解决方案总结

    最近公司比较忙,一直忙着写代码做新的应用,一连上线了几个应用,我们也是忙得焦头烂额的,都没时间做总结,今天趁APP审核期间,总结一下近期上传App Store遇到的一些问题和解决方法,以便以后查阅. ...

  10. bay——安装_RAC11g_LC_ASM方式_测试环境.txt

    ★★★____★☆★〓〓〓〓→VMware vSphere Client6.0 https://10.20.4.200/ 下载Vwmare IP:10.20.4.200-------账号:root-- ...