使用BackgroundWorker组件 一文中,阐述了在Winform编程中,使用BackgroundWorker组件实现异步调用,本文主要讲述利用委托实现异步。

以下描述摘抄于MSDN:

异步委托提供以异步方式调用同步方法的能力。

当同步调用委托时,Invoke()方法直接对当前线程调用目标方法;

当异步调用委托时,CLR将对请求进行排队并立即返回到调用方,将对来自线程池的线程调用该目标方法,提交请求的原始线程继续与目标方法并行执行,该目标方法是对线程池线程运行的.

1)、BeginInvoke()方法

BeginInvoke()方法启动异步调用,它与需要异步执行的方法具有相同的参数。

另外,还有两个可选参数:第一个参数是AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第二个参数是用户定义的对象,该对象可向回调方法传递信息;

BeginInvoke立即返回,不等待异步调用完成;

BeginInvoke返回IAsyncResult,这个结果可用于监视异步调用的进度;

2)、EndInvoke()方法

EndInvoke()方法检索异步调用的结果;

在调用BeginInvoke()方法后,可以随时调用EndInvoke()方法,如果异步调用尚未完成,则EndInvoke()方法将一直阻止调用线程,直到异步调用完成后才允许调用线程执行;

EndInvoke()的参数需要异步执行的方法的out和ref参数以及由BeginInvoke()返回的IAsyncResult。

下面通过代码阐述异步委托:

代码一,同步执行:
  1. public delegate int MathDelegate(int x);
    public class MathClass
    {
    public int Add(int x)
    {
    Thread.Sleep(10000);//此处模拟长时间执行的任务
    return x + x;
    }
    }
  2.  
  3. public class Program
    {
    public static void Main(string[] args)
    {
    MathClass addClass = new MathClass();
    MathDelegate mathDel = new MathDelegate(addClass.Add);
  4.  
  5. //同步执行
    int syncResult = mathDel(8);
    Console.WriteLine("Sync Proccessing operation...");//这一行只有SyncMethod完成以后才能显示
    Console.WriteLine("Sync Result is: {0}", syncResult);
  6.  
  7. Console.ReadLine();
    }
    }
    当程序执行到 int syncResult = mathDel(8); 的时候,主线程将等待至少10秒的时间(Add方法的执行),才能执行
  1. 后面的代码,也即在期间,应用程序没有响应,不能执行其他的任何操作,直到Add方法返回结果。
代码二,异步执行:

我们稍微修改一下Main的代码:

  1. public static void Main(string[] args)
    {
    MathClass addClass = new MathClass();
    MathDelegate mathDel = new MathDelegate(addClass.Add);
  2.  
  3. IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
    Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
    int asyncReuslt = mathDel.EndInvoke(async);
    Console.WriteLine("Result is: {0}", asyncReuslt);
  4.  
  5. Console.ReadLine();
    }

在这段代码中,在开始并没有直接调用方法,而是使用BeginInvoke()方法,返回IAsyncResult 对象。

代码三,IsCompleted,轮询异步调用完成
使用IAsyncResult实例的IsCompleted属性,以获取异步操作是否已完成的指示,如果操作完成则为True,否则为False。

修改一下Main的代码:

  1. public static void Main(string[] args)
    {
    MathClass addClass = new MathClass();
    MathDelegate mathDel = new MathDelegate(addClass.Add);
  2.  
  3. IAsyncResult async = mathDel.BeginInvoke(9, null, null);//在另外的线程里,调用Add方法
    Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备
  4.  
  5. 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);
  6.  
  7. Console.ReadLine();
    }
代码四,AsyncCallback,异步调用完成时执行回调方法

如果启动异步调用的线程不需要是处理结果的线程,则可以在调用完成时执行回调方法;

如果要使用回调方法,必须将引用回调方法AsyncCallback委托传递给BeginInvoke()方法,也可以传递包含回调方法将要使用的信息的对象。

修改一下Main的代码:

  1. public static void Main(string[] args)
    {
    MathClass addClass = new MathClass();
    MathDelegate mathDel = new MathDelegate(addClass.Add);
  2.  
  3. IAsyncResult async = mathDel.BeginInvoke(9, new AsyncCallback(CompleteMethod), "信息来自于主线程");//在另外的线程里,调用Add方法
    Console.WriteLine("Async Proccessing operation...");//立即打印到终端设备

  4. Console.ReadLine();
    }
    private static void CompleteMethod(IAsyncResult async)
    {
    AsyncResult ar = (AsyncResult)async;
  5.  
  6. MathDelegate del = (MathDelegate)ar.AsyncDelegate;
    int result = del.EndInvoke(async);
  7.  
  8. string mainTheadMsg = ar.AsyncState as string;
    Console.WriteLine("{0}, Result is: {1}", mainTheadMsg, result);
    }
  1. Add方法调用完成以后,调用 CompleteMethod 方法
结束

C# 异步示例代码的更多相关文章

  1. python开源项目及示例代码

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

  2. C/C++ 开源库及示例代码

    C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...

  3. python开源项目及示例代码(转)

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

  4. 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )

    作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912 相关地址介绍 : -- Universal I ...

  5. 异步nodejs代码的同步样子写法样例

    异步nodejs代码的同步样子写法样例 js的异步嵌套太深代码将不好看.尤其在用node的时候这种情况会大量出现. 这里用node连接redis,做一个用户注册的简单例子来说明.例如用redis做存储 ...

  6. 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

  7. 2.NetDh框架之简单高效的日志操作类(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

  8. 50.AngularJs directive详解及示例代码

    转自:https://www.cnblogs.com/best/tag/Angular/ 本教程使用AngularJs版本:1.5.3 AngularJs GitHub: https://github ...

  9. Redis简单命令(部分示例代码)

    一.redis文件夹下的可执行文件(文章尾部有示例代码) 可执行文件 作用 redis-server 启动redis redis-cli redis命令行工具 redis-benchmark 基准测试 ...

随机推荐

  1. angular2的ElementRef在组件中获取不到

    angular2的ElementRef在组件中获取不到 angular2不推荐操作dom,但是实际应用中不可避免的需要使用到dom操作,怎么操作,官方文档提供了一系列api(ElementRef,Vi ...

  2. linux tee

    tee 功能说明:读取标准输入的数据,并将其内容输出成文件. 语 法:tee [-ai][--help][--version][文件...] 补充说明:tee指令会从标准输入设备读取数据,将其内容输出 ...

  3. 使用摄像头或视频运行 ORB-SLAM2 SLAM14讲 第一次课后作业

    参考:视觉SLAM十四讲(第一章作业) 深蓝上高博的第一讲课后题: 题目:6 * 使用摄像头或视频运行 ORB-SLAM2(3 分,约 1 小时)请注意本题为附加题.了解⼀样东西最快的⽅式是⾃⼰上⼿使 ...

  4. 超级简单的Memcache入门

    Memcache 就是一个数据库,将数据保存在内存中 常用于缓存服务器,保存操作频繁,丢失无所谓的数据 启动选项 -d 是一个守护进程 -m 内存分配 -u 用户 -l 监听地址 -p 端口 -c 最 ...

  5. whil

    while true; do select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 m ...

  6. Ping 笔记

    Ping  笔记 查看网络间的连通性. 当设备与PC在同一局域网中(连接同一路由器),设备与PC互Ping对方,若只有其中一个掉线连不上,两者可能存在网络端口的问题, 若设备与PC同时掉线,则为路由器 ...

  7. egret编译 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed process out of memory解决

    egret 白鹭编译时异常提示: FATAL ERROR: CALL_AND_RETRY_0 Allocation failed process out of memory.  编译时内存溢出, 因为 ...

  8. python if,循环的练习

    1.变量值的交换 ​ s1='alex'​ s2='SB' (s1,s2) = (s2,s1) 2.有存放用户信息的列表如下,分别存放用户的名字.年龄.公司信息 userinfo={ 'name':' ...

  9. NOIP 2018 Day1

    Fei2Xue@Lian$Tian! 三道原题qwq真的凉 半年前看到有人发说说,梦见省选打开题目,是Please contact lydsy2012@163.com! 没想到一语成谶 大众分300 ...

  10. 软件职位进阶--立Flag

    PS:是我从看过的书籍<软件测试进阶之路>上摘录的 很喜欢:深耕细作一词,可以走管理leader方向,但我更愿意是技术掌握到手后,兼职管理岗位. 庆幸吧,脚踏实地,没有上来就学自动化,所以 ...