c#中异步编程
异步是现实生活中的很多现象的一种抽象。比如分工合作在很多时间段就是异步合作。异步中也一般要涉及委托方法。c#有3种模式的异步编程:异步模式,基于事件的异步模式,基于任务的异步模式(TAP).
一. FrameWork 4.0之前的线程世界
在.NET FrameWork 4.0之前,如果我们使用线程。一般有以下几种方式:
- 使用System.Threading.Thread 类,调用实例方法Start()开启一个新线程,调用Abort()方法来提前终止线程。
- 使用System.Threading.ThreadPool类,调用静态方法QueueUserWorkItem(),将方法放入线程池队列,线程池来控制调用。
- 使用BeginInvoke,EndInvoke,BeginRead,EnRead,BeginWrite,EndWrite等一系列的异步方法。
- 使用System.ComponentModel.BackgroundWorker控件,调用实例方法RunWorkerAsync(),开启一个新线程。
二. .Net 传统异步编程概述
- 异步编程模型 (APM),在该模型中异步操作由一对 Begin/End 方法(如 FileStream.BeginRead 和 Stream.EndRead)表示。
- 基于事件的异步模式 (EAP),在该模式中异步操作由名为“操作名称Async”和“操作名称Completed”的方法/事件对(例如 WebClient.DownloadStringAsync 和 WebClient.DownloadStringCompleted)表示。 (EAP 是在 .NET Framework 2.0 版中引入的,在silverlight或者wpf变成中经常用到)。
三. Task 的优点以及功能
- 在任务启动后,可以随时以任务延续的形式注册回调。
- 通过使用 ContinueWhenAll 和 ContinueWhenAny 方法或者 WaitAll 方法或 WaitAny 方法,协调多个为了响应 Begin_ 方法而执行的操作。
- 在同一 Task 对象中封装异步 I/O 绑定和计算绑定操作。
- 监视 Task 对象的状态。
- 使用 TaskCompletionSource 将操作的状态封送到 Task 对象。
第一种 异步模式
public class 异步调用
{
static void Main()
{
Console.WriteLine("===== 异步调用 AsyncInvokeTest =====");
AddHandler handler = new AddHandler(加法类.Add);
//IAsyncResult: 异步操作接口(interface)
//BeginInvoke: 委托(delegate)的一个异步方法的开始
IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
Console.WriteLine("继续做别的事情。。。");
//异步操作返回 EndInvoke方式会阻塞主线程 需要等待异步线程调用完毕 才会执行
Console.WriteLine(handler.EndInvoke(result));
Console.ReadKey();
}
}
public class 异步回调
{
static void Main()
{
Console.WriteLine("===== 异步回调 AsyncInvokeTest =====");
AddHandler handler = new AddHandler(加法类.Add);
//异步操作接口(注意BeginInvoke方法的不同!)
IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回调函数),"AsycState:OK");
Console.WriteLine("继续做别的事情。。。");
Console.ReadKey();
} static void 回调函数(IAsyncResult result)
{
//result 是“加法类.Add()方法”的返回值
//AsyncResult 是IAsyncResult接口的一个实现类,空间:System.Runtime.Remoting.Messaging
//AsyncDelegate 属性可以强制转换为用户定义的委托的实际类。
AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
//或者 AddHandler handler=result.AsyncState as AddHandler;
Console.WriteLine(handler.EndInvoke(result));
Console.WriteLine(result.AsyncState);
}
}
利用lambda表达式简单写法 (这个很常用。一定要理解和学会。)
// public delegate string TakesAWhileDelegate(int data1, int data2); 定义一个委托
TakesAWhileDelegate dl = (a, b) => { return (a + b).ToString(); }; //委托 实例化
dl.BeginInvoke(1, 12, result => { //回调方法 实例化
string str=dl.EndInvoke(result); //EndInvoke方法取回结果
Console.WriteLine("取到异步的结果了result={0}", str);
}, null);
第二种 基于事件的异步模式
.net中很多类的方法都定义了同步和异步两种模式,例如WebClient类,就定义了DownloadStringAsync基于事件的异步模式。
WebClient wc = new WebClient();
string strUI = "我是主线程中的元素";
wc.Encoding = Encoding.UTF8;
//首先实例化 Completed事件。 注意:可以直接访问UI线程中的元素
// public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e);
wc.DownloadStringCompleted += (sender1, e1) => { //e1 存放结果
Console.WriteLine(strUI);
string str = e1.Result;
Console.WriteLine(str);
};
wc.DownloadStringAsync(new Uri("http://www.baidu.com"));
Console.WriteLine("继续主线程,不会因为访问网站而阻塞");
第三种 基于任务的异步模式(Task,await,async关键字)
private void button21_Click(object sender, EventArgs e)
{
Console.WriteLine("主线程已经开始了");
CallerWithAsync(); //调用基于任务的异步方法
Console.WriteLine("主线程已经结束了"); }
//创建基于任务的异步方法
private async void CallerWithAsync()
{
//async(方法修饰符)和await必须成对出现。顺序执行
string result = await GetAsync("第1个"); //等待 方法执行结果 阻塞线程。编译器把await关键字后的所有代码放进ContinueWith方法的代码块中
string result2 = await GetAsync("第2个");
Console.WriteLine("任务第3");
}
//通过任务使同步方法异步化
private Task<string> GetAsync(string name)
{
return Task.Run<string>(() => {
Thread.Sleep(2000);
Console.WriteLine(name);
return name; });
}
TASK的用法 请参考这篇文章
c#中异步编程的更多相关文章
- 谈谈c#中异步编程模型的变迁
大家在编程过程中都会用到一些异步编程的情况.在c#的BCL中,很多api都提供了异步方法,初学者可能对各种不同异步方法的使用感到迷惑,本文主要为大家梳理一下异步方法的变迁以及如何使用异步方法. Beg ...
- Web worker 与JS中异步编程的对比
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...
- JavaScript中异步编程
一 关于事件的异步 事件是JavaScript中最重要的一个特征,nodejs就是利用js这一异步而设计出来的.所以这里讲一下事件机制. 在一个js文件中,如果要运行某一个函数,有2中手段,一个就是直 ...
- Java网络编程中异步编程的理解
目录 前言 一.异步,同步,阻塞和非阻塞的理解 二.异步编程从用户层面和框架层面不同角度的理解 用户角度的理解 框架角度的理解 三.为什么使用异步 四.理解这些能在实际中的应用 六.困惑 参考文章 前 ...
- C#中异步编程异常的处理方式
异步编程异常处理 在同步编程中,一旦出现错误就会抛出异常,我们可以使用try-catch来捕捉异常,未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.但是对于异步编程来说,异常处理一直 ...
- promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解
* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...
- 简单实现异步编程promise模式
本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多 ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- 深入浅出node(4) 异步编程
一)函数式编程基础 二)异步编程的优势和难点 2.1 优势 2.2 难点 2.2.1 异常处理 2.2.2 函数嵌套过深 2.2.3 阻塞 2.2.4 多线程编程 2.2.5 异步转同步 三)异步编程 ...
随机推荐
- Django web 应用 http 协议 web框架
一:什么是web 应用程序 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 应用程序有两种模式C/S.B/S. ...
- 数据挖掘算法以及其实现zz
实验一 分类技术及其应用 实习要求: 基于线性回归模型拟合一个班学生的学习成绩,建立预测模型.数据可由自己建立100个学生的学习成绩. 1) 算法思想: 最小二乘法 设经验方程是y=F(x ...
- linux中的 tar命令的 -C 参数,以及其它一些参数
tar命令的-C参数 $ tar -cvf file2.tar /home/usr2/file2 tar: Removing leading '/' from members names hom ...
- Swoole2.0协程客户端连接池的实现
Swoole2.0官方默认的实例是短连接的,在请求处理完毕后就会切断redis或mysql的连接.实际项目可以使用连接池实现复用. 实现原理也很简单,使用SplQueue,在请求到来时判断资源队列中是 ...
- shell脚本生成xml文件
今天把这段时间学习完shell后完成工作上的一个小案件整理了一下,分享给大家! 说来也巧了,作为一个刚刚毕业半年的菜鸟,进入公司后,听公司的大牛推荐学习linux--”鸟哥的私房菜“,基本上是从去年8 ...
- [label][responsive-web-design]网页响应测试各种尺寸的工具
因为现在各种各样的尺寸上网设备 ,所以我们现在的网页设计都必须要兼容到各种尺寸的屏幕,必须测试各个 size下面的页面布局与排版. 一个开发人员是不可能拥有各种设备来进行测试,那么有没有什么便捷的工具 ...
- Oracle EBS R12多组织访问架构
关于R12的新特性Multi-Org Access Control(MOAC).Oracle宣传的好处主要有:1.enable users to access to secured data in o ...
- 让FIREDAC记录数据库的异常日志
默认FIREDAC不会记录数据库的异常. 比如典型的,提交的时候,非空字段没有给值. 某些人还以为FIREDAC不能捕获数据库的异常,其实FIREDAC是可以捕获并处理数据库的异常事件的. 方法异常简 ...
- UWP多线程枚举安全的List
最近在做windows runtime下APP开发的工作.在Service层请求返回后,往往会通过回调的形式来通知UI更新数据.多个线程操作经常出现foreach抛出异常:System.Invalid ...
- 在Ubuntu16.04里面安装Gogland!
一,安装 把linux版本的Gogland拷贝到Ubuntu16.04里面,随后在想要存放它的地方解压缩,这样就完成了安装! 二,让Gogland可以快速启动 linux版本的Gogland的启动是用 ...