使用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# 异步示例代码的更多相关文章

  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. Shell脚本出现$'\r': command not found

    Centos7下执行shell脚本报错如下 [root@ip---- ~]# sh install_zabbix_agent.sh install_zabbix_agent.: $'\r': comm ...

  2. centos7远程安装oracle11g R2详细教程-解决一切问题

    相关链接与资源: sqldevelper(各种操作系统的oracle客户端) http://www.oracle.com/technetwork/cn/developer-tools/sql-deve ...

  3. 远程访问服务器tensorboard

    转自https://blog.csdn.net/Hansry/article/details/83004648 1. 在登录远程服务器的时候使用命令: : server_name@server.add ...

  4. 发布一个PHP包到Packagist, 然后使用Composer安装

    Composer 能够方便的进行项目的依赖管理,  当我们发布一个包并且希望别人通过Composer安装的时候, 就需要将包发布到Composer的包仓库Packagist上面. 下面进行详细的说明一 ...

  5. Java核心-多线程-并发控制器-CountDownLatch倒数闩

    1.基本概念 CountDownLatch,中文名倒数闩,jdk并发工具包中一个并发控制器,它抽象了一个常见的多线程并发场景,开发人员使用它可以写出同时兼顾线程安全性与高效率的代码. 2.抽象模型 相 ...

  6. gevent-websocket初识

    初试 from flask import Flask, request from geventwebsocket.handler import WebSocketHandler from gevent ...

  7. android 中activity重启的方法

    private void reLoadActivity(){ Intent intent = new Intent(context, SettingsActivity.class); intent.s ...

  8. sprinmvc与 Struct2框架的区别

    1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上Spr ...

  9. koa-passport实现本地验证

    安装 yarn add koa-passport passport-local 先看下passport.js登录策略,判断用户和密码 const passport = require('koa-pas ...

  10. vue登录注册及token验证

    // router.jsimport Vue from 'vue'import VueRouter from 'vue-router' Vue.use(VueRouter) const routes ...