C# 异步示例代码
在 使用BackgroundWorker组件 一文中,阐述了在Winform编程中,使用BackgroundWorker组件实现异步调用,本文主要讲述利用委托实现异步。
以下描述摘抄于MSDN:
异步委托提供以异步方式调用同步方法的能力。
当同步调用委托时,Invoke()方法直接对当前线程调用目标方法;
当异步调用委托时,CLR将对请求进行排队并立即返回到调用方,将对来自线程池的线程调用该目标方法,提交请求的原始线程继续与目标方法并行执行,该目标方法是对线程池线程运行的.
1)、BeginInvoke()方法
BeginInvoke()方法启动异步调用,它与需要异步执行的方法具有相同的参数。
另外,还有两个可选参数:第一个参数是AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第二个参数是用户定义的对象,该对象可向回调方法传递信息;
BeginInvoke立即返回,不等待异步调用完成;
BeginInvoke返回IAsyncResult,这个结果可用于监视异步调用的进度;
2)、EndInvoke()方法
EndInvoke()方法检索异步调用的结果;
在调用BeginInvoke()方法后,可以随时调用EndInvoke()方法,如果异步调用尚未完成,则EndInvoke()方法将一直阻止调用线程,直到异步调用完成后才允许调用线程执行;
EndInvoke()的参数需要异步执行的方法的out和ref参数以及由BeginInvoke()返回的IAsyncResult。
下面通过代码阐述异步委托:
代码一,同步执行:
public delegate int MathDelegate(int x);
public class MathClass
{
public int Add(int x)
{
Thread.Sleep(10000);//此处模拟长时间执行的任务
return x + x;
}
} public class Program
{
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add); //同步执行
int syncResult = mathDel(8);
Console.WriteLine("Sync Proccessing operation...");//这一行只有SyncMethod完成以后才能显示
Console.WriteLine("Sync Result is: {0}", syncResult); Console.ReadLine();
}
}
当程序执行到 int syncResult = mathDel(8); 的时候,主线程将等待至少10秒的时间(Add方法的执行),才能执行
后面的代码,也即在期间,应用程序没有响应,不能执行其他的任何操作,直到Add方法返回结果。
代码二,异步执行:
我们稍微修改一下Main的代码:
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add); IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt); Console.ReadLine();
}
在这段代码中,在开始并没有直接调用方法,而是使用BeginInvoke()方法,返回IAsyncResult 对象。
代码三,IsCompleted,轮询异步调用完成
使用IAsyncResult实例的IsCompleted属性,以获取异步操作是否已完成的指示,如果操作完成则为True,否则为False。
修改一下Main的代码:
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add); IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备 int i = 1;
while (async.IsCompleted==false)
{
Thread.Sleep(i * 1000);
Console.WriteLine("IsCompleted:{0},{1}", async.IsCompleted, i);
i++;
}
int asyncReuslt = mathDel.EndInvoke(async);
Console.WriteLine("Result is: {0}", asyncReuslt); Console.ReadLine();
}
代码四,AsyncCallback,异步调用完成时执行回调方法
如果启动异步调用的线程不需要是处理结果的线程,则可以在调用完成时执行回调方法;
如果要使用回调方法,必须将引用回调方法AsyncCallback委托传递给BeginInvoke()方法,也可以传递包含回调方法将要使用的信息的对象。
修改一下Main的代码:
public static void Main(string[] args)
{
MathClass addClass = new MathClass();
MathDelegate mathDel = new MathDelegate(addClass.Add); IAsyncResult async = mathDel.BeginInvoke(9, new AsyncCallback(CompleteMethod), "信息来自于主线程");//在另外的线程里,调用Add方法
Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
Console.ReadLine();
}
private static void CompleteMethod(IAsyncResult async)
{
AsyncResult ar = (AsyncResult)async; MathDelegate del = (MathDelegate)ar.AsyncDelegate;
int result = del.EndInvoke(async); string mainTheadMsg = ar.AsyncState as string;
Console.WriteLine("{0}, Result is: {1}", mainTheadMsg, result);
}
Add方法调用完成以后,调用 CompleteMethod 方法
结束
C# 异步示例代码的更多相关文章
- python开源项目及示例代码
本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...
- C/C++ 开源库及示例代码
C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...
- python开源项目及示例代码(转)
本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...
- 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912 相关地址介绍 : -- Universal I ...
- 异步nodejs代码的同步样子写法样例
异步nodejs代码的同步样子写法样例 js的异步嵌套太深代码将不好看.尤其在用node的时候这种情况会大量出现. 这里用node连接redis,做一个用户注册的简单例子来说明.例如用redis做存储 ...
- 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
- 2.NetDh框架之简单高效的日志操作类(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
- 50.AngularJs directive详解及示例代码
转自:https://www.cnblogs.com/best/tag/Angular/ 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: https://github ...
- Redis简单命令(部分示例代码)
一.redis文件夹下的可执行文件(文章尾部有示例代码) 可执行文件 作用 redis-server 启动redis redis-cli redis命令行工具 redis-benchmark 基准测试 ...
随机推荐
- win2008安装并配置zabbix3.4 agent
agent 下载地址: https://www.zabbix.com/download_agents 下载解压后有2个文件夹,一个是bin,存放32位和64位执行程序,一个是conf目录存放着配置文件 ...
- TCL 引用同目录下其他脚本文件--source
方法一: source [file join [file dirname [info script]] Export_inp_by_loadstep.tcl] 方法二: source [file jo ...
- 时间规划在Optaplanner上的实现
在与诸位交流中,使用较多的生产计划和路线规划场景中,大家最为关注的焦点是关于时间的处理问题.确实,时间这一维度具有一定的特殊性.因为时间是一维的,体现为通过图形表示时,它仅可以通过一条有向直线来表达它 ...
- L1、L2范数理解
读了博主https://blog.csdn.net/a493823882/article/details/80569888的文章做简要的记录. 范数可以当作距离来理解. L1范数: 曼哈顿距离,是机器 ...
- 玩转MQTT-阿里云之MQTT使用
引言 前两年买一款物联网控制板,当时把玩了一阵之后,验证了下串口通讯.MODBUS协议实现.TCP/UDP/DNS/MQTT通讯(基于GPRS)后,就放到角落里吃灰了呵. 最近收到阿里云的优惠推送,说 ...
- MSDE2008安装备忘
MSDE2008安装备忘(适用于WIN7 8 10) 1.系统中必须要VC8.0,即VC2005运行库.2.系统中必须要有.net framework2.0.3.5.4.6运行库.3.windows防 ...
- 联想IDEAPAD 320C-15笔记本显卡驱动问题
联想IDEAPAD 320C-15笔记本显卡驱动问题核显Intel(R) HD Graphics 620独显AMD Radeon(TM) 530必须安装好核显驱动,独显驱动才能正常工作,否则设备管理器 ...
- 为什么HTML中的多个空格或是回车在浏览器上只能显示出一个?
我们在学习HTML的时候可能书本或是老师会告诉我们一件事,就是在HTML中不管我们在两个文本之间加上多少连续的空格或是回车,到了浏览器里面只能显示出一个来.但是我们从来不知道为什么. 原因很简单,因为 ...
- 0002-小牛学堂大数据24期视频-架构Hadoop-Spark
- json,pickle,shelve模块,xml处理模块
常用模块学习—序列化模块详解 什么叫序列化? 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes. 为什么要序列化? 你打游戏过程 ...