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 基准测试 ...
 
随机推荐
- 基于javaMail的邮件发送--excel作为附件
			
基于JavaMail的Java邮件发送 Author xiuhong.chen@hand-china.com Desc 简单邮件发送 Date 2017/12/8 项目中需要根据物料资质的状况实时给用 ...
 - DNS搭建
			
构建主从服务DNS 1.主服务名字:ns1.amber.com #hostname ns1.amber.com bash 刷新一下 #bash 2.Vim /etc/hosts 3.Vim /etc/ ...
 - 在已安装64位oracle的服务器安装32位客户端
			
应用场景:服务器操作系统是win2012 64位,原先安装了64位oracle12,后来系统增加导入excel的功能,网站必须启用32位兼容模式,这时候发现原有的页面打不开,提示: 试图加载格式不正确 ...
 - php7带来的性能升级
			
前言本文是一篇讲座听后+后续研究的总结. 话说当年追时髦,php7一出就给电脑立马装上了,php5和php7共存,也是立马写了个超级耗时间的循环脚本测了一番,确实php7给力很多,然后也是注意了一些新 ...
 - java 通信
			
UDP package com.le; import org.junit.Test; import java.io.IOException; import java.net.DatagramPacke ...
 - 为什么HTML中的多个空格或是回车在浏览器上只能显示出一个?
			
我们在学习HTML的时候可能书本或是老师会告诉我们一件事,就是在HTML中不管我们在两个文本之间加上多少连续的空格或是回车,到了浏览器里面只能显示出一个来.但是我们从来不知道为什么. 原因很简单,因为 ...
 - Nginx配置CI框架问题(Linux平台下Centos系统)
			
CI框架:官方文档 http://codeigniter.org.cn/user_guide/index.html CI框架的数据流程图如下: 其中:index.php作为入口文件,在安装好CI框架后 ...
 - RIDE创建工程和测试套件和用例--书本介绍的入门方法,自己整理实践下
			
1.选择File->New Project 2.弹出的New Project对话框,在Name文本框输入一个名词,如“TestProject-0805”,右侧选中“Directory”,选中建立 ...
 - .net core2 api
			
[Produces("application/json")][Consumes("application/json")][Consumes("appl ...
 - SpringMVC Controller接收前台ajax的GET或POST请求返回各种参数
			
这几天写新项目遇到这个问题,看这位博主总结得不错,懒得写了,直接转!原文:http://blog.csdn.net/yixiaoping/article/details/45281721原文有些小错误 ...