博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
阅读量:4682 次
发布时间:2019-06-09

本文共 4333 字,大约阅读时间需要 14 分钟。

[.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序

本节导读:

本节主要说明使用异步进行程序设计的优缺点及如何通过异步编程.

使用传统方法BeginInvoke / EndInvoke来实现异步。

使用async/await 创建异步方法和事件。

通过异步编程创建具有快速响应和可伸缩性的应用程序。 

读前必备:

A.委托 

B.事件 

1.异步程序设计的优缺点:

A.让用户界面快速响应;对于耗时操作阻塞UI线程,通过异步回调可使用UI快速响应。

B.创建高伸缩性的应用。对于服务端应用,创建更多线程来处理消耗资源较多,使用异步可使用主线程继续工作,不需要等待返回。使用程序具有更好的伸缩性。

对于异步的缺点,最主要一点就是比创建同步程序难度大一些,首先使用传统的方法创建异步,比起同步更容易出错。不过随着.NET的不断发展和第三方异步组件的丰富,创建异步应用程序也变得越来越简单了。

2.异步的实现

对于.NET中的异步编程,.NET在各个方向都几乎提供了同步和异步的两个方式来实现,在这里我们不能把.NET中全部的异步编程方法都列举出来了,下面介绍几种常用且实用的异步方法。

3.使用BeginInvoke / EndInvoke实现异步

3.1 简单的异步示例

下面看一个简单的示例: 

//使用一个有返回值的泛型委托来执行BeginInvokeFunc
myFunc = new Func
(()=>{ Thread.Sleep(10); return "我是异步执行完成的返回值 当前时间:" + System.DateTime.Now.ToString();});IAsyncResult asynResult = myFunc.BeginInvoke(null, null);//在异步没有完成前,可以做别的事while (!asynResult.IsCompleted){ //当不是true时,就执行这里的代码 Console.WriteLine("当前异步是否完成:" + asynResult.IsCompleted + " 当前时间:" + System.DateTime.Now.ToString());}string result = myFunc.EndInvoke(asynResult);//当是true时,就将结果返回显示Console.WriteLine(result);

 运行结果如下:

 

在异步没有完成时,可以继续工作做一些想做的事,异步完成后返回结果。

3.2 使用异步的超时 WaitOne 判断异步完成

除了上面使用IsCompleted来判断异步完成之外,也可以使用超时来判断异步的完成情况

示例如下 :

//使用一个有返回值的泛型委托来执行BeginInvokeFunc
myFunc = new Func
(()=>{ int i = 0; while (i<99999999) ++i; return "异步执行完成的返回值" + (i).ToString() + " 当前时间:" + System.DateTime.Now.ToString(); });IAsyncResult asynResult = myFunc.BeginInvoke(null, null);while (!asynResult.AsyncWaitHandle.WaitOne(10, false)) Console.Write("*");string result = myFunc.EndInvoke(asynResult);Console.Write("\n");Console.WriteLine(result);

运行结果如下:

3.3 回调

毕竟上述两种等待不是一个好的方法。我们在前端开发中使用过ajax的同学肯定知道,前端中异步使用一个回调函数在异步完成后完成我们想要做的事,.NET自然也有类似的回调方法,

看示例:

//使用一个有返回值的泛型委托来执行BeginInvokeFunc
myFunc = new Func
(()=>{ int i = 0; while (i<99999999) ++i; return "异步执行完成的返回值" + (i).ToString() + " 当前时间:" + System.DateTime.Now.ToString(); });IAsyncResult asynResult = myFunc.BeginInvoke((result) =>{ string rst = myFunc.EndInvoke(result); Console.WriteLine("异步完成了,我该返回结果了!"); Console.WriteLine(rst);}, null);

运行结果如下 :

3.4 其它组件中的Begin\End异步方法

除了BeginInvoke / EndInvoke之外,.NET在很多类中提供了异步的方法,

如System.Net.HttpWebRequest类的BeginGetResponse和EndGetResponse方法,

这里不再一一列举了,使用方法和上面的示例类似。

 4. async/await  

.NET 5.0 以后,让异步编程变得更加简单了,我们介绍一下async和await。 

它让我们编写异步程序变得和同步一样简单,不但减少了代码量,而且不会因为异步让我们程序逻辑被打乱。 

4.1 异步方法 

下面使用async 和 await关键字来创建一个异步方法,

在第一个方法里调用第二个异步方法,

第二个异步方法中使用了多线程。

听起来很绕口,不过整个代码编写和同步方法没有什么区别,只是多一个关键字。

static void Main(string[] args){    Console.WriteLine("主线程开始..");    AsyncMethod();    Thread.Sleep(1000);    Console.WriteLine("主线程结束..");    Console.ReadKey();}static async void AsyncMethod(){    Console.WriteLine("开始异步方法");    var result = await MyMethod();    Console.WriteLine("异步方法结束");}static async Task
MyMethod(){ for (int i = 0; i < 5; i++) { Console.WriteLine("异步执行" + i.ToString() + ".."); await Task.Delay(1000); //模拟耗时操作 } return 0;}

运行结果如下: 

 

4.2 异步事件

下面使用一个WinForm应用程序来测试一下异步事件,我们创建一个同步的Click事件和一个异步的Click事件,先触发异步,然后紧接着触发同步,看一下运行结果。 

//同步事件private void button2_Click(object sender, EventArgs e){    textBox1.Text += "同步执行开始..\r\n";              MyMethodFirst();    textBox1.Text += "同步执行结束..\r\n";          }//同事事件调用方法int MyMethodFirst(){    for (int i = 0; i < 5; i++)    {        textBox1.Text += "同步执行" + i.ToString() + "..\r\n";                   }    return 0;}//异步事件private async  void button3_Click(object sender, EventArgs e){    textBox1.Text += "异步执行开始..====\r\n";    await MyMethodSencond();    textBox1.Text += "异步执行结束..====\r\n";     }//异步事件调用方法async Task
MyMethodSencond(){ for (int i = 0; i < 5; i++) { textBox1.Text += "异步执行" + i.ToString() +" ..====\r\n"; await Task.Delay(1000); //模拟耗时操作 } return 0;}

 运行结果如下:

5. 本节要点

A.使用传统方法BeginInvoke / EndInvoke来实现异步

B.使用async/await 创建异步方法和事件

==============================================================================================

<如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>

<对本系列文章阅读有困难的朋友,请先看>

<转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

.NET 技术交流群:467189533

==============================================================================================

转载于:https://www.cnblogs.com/yubinfeng/p/4687904.html

你可能感兴趣的文章
前端MVC实践之hellorocket——by张舒彤
查看>>
OptimalSolution(2)--二叉树问题(3)Path路径问题
查看>>
IPC 之 Messenger 的使用
查看>>
macos 下usb键盘问题.
查看>>
SQL函数学习(十六):STUFF()函数
查看>>
Apache Hadoop 和Hadoop生态圈
查看>>
Ctrl+Enter 选中文本提交
查看>>
android WIFI
查看>>
常用的匹配正则表达式和实例
查看>>
小组成员及其git链接
查看>>
SQL case when else
查看>>
MVc Identity登陆锁定
查看>>
cdn连接失败是什么意思_关于CDN的原理、术语和应用场景那些事
查看>>
ultraedit26 运行的是试用模式_免费试用U盘数据恢复工具 – 轻松找回U盘丢失的各种数据!...
查看>>
plsql 查询存储过程死锁语句_插入语句/存储过程死锁
查看>>
bootstrap table 收缩_bootstrap-table方法之:expandRow-collapseRow,展开或关闭当前行数据...
查看>>
jsp跳转到本身页面_五种JSP页面跳转方法详解
查看>>
mysql r_mysql:’r’是什么意思?
查看>>
无法加载 mysql 扩展_请检查您的 php 配置. - 文档_无法载入 mysql 扩展 请检查 PHP 配置...
查看>>
非空 默认 男 mysql_MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束...
查看>>