异步方法

  当一个线程调用方法后,直到方法执行完毕,线程才继续执行,这种方法被称为同步方法。然而,有些方法执行时间可能非常长,比如串口操作或访问网络,这样线程被阻塞,而无法响应用户的其他请求。这种情况通常是无法忍受的,所以这时我们应该使用异步方法。

  异步方法的原理是,在方法调用前为异步方法指定一个回调函数,方法调用后被线程池中的一个线程接管,执行该方法。主线程立即返回,继续执行其他工作或响应用户请求。如果异步方法执行完毕,回调函数被自动执行,以处理异步方法的调用结果。

  如何实现异步方法呢?C#通过异步委托调用BeginInvoke和EndInvoke方法来实现异步方法。

BeginInvoke方法原型:

  IAsyncResult BeginInvoke(......, AsyncCallback callback, object o);
  ......表示异步委托中定义的参数列表。
  AsyncCallback参数是一个用于回调函数的委托,它的原型为:
  public delegate void AsyncCallback(IAsyncResult ar)。其中IAsyncResult参数用于包装异步方法的执行结果。
  Object参数用于在主线程与回调函数间传递一些附加信息,如同步信息。

EndInvoke方法原型:

  xxx EndInvoke(IAsyncResult result);
  xxx表示异步委托原型中定义的返回数据类型,IAsyncResult用于包装异步方法的执行结果。

  这么看着是不是有点迷糊?看个例子就明白了:


using System;
using System.Threading;
using System.Runtime.Remoting.Messaging; namespace ProcessTest
{
class Program
{
//异步调用执行完成同步信号
static AutoResetEvent ev =new AutoResetEvent(false);
//定义委托
publicdelegateint Deleg(int a, int b); staticint WriteSum(int a, int b)
{
//显示当前线程ID号及Sum值
Console.WriteLine("执行WriteSum的线程ID为:{0},Sum = {1}", Thread.CurrentThread.ManagedThreadId, a + b);
return a + b;
} //回调函数
staticvoid SumDone(IAsyncResult async)
{
//等待1秒,模拟线程正在执行其他工作
Thread.Sleep(); //async中包装了异步方法执行的结果
//从操作结果async中还原委托
Deleg proc = ((AsyncResult)async).AsyncDelegate as Deleg;
//获取异步方法的执行结果
int sum = proc.EndInvoke(async); //显示结果
Console.WriteLine("执行SumDone的线程ID为:{0},Sum = {1}", Thread.CurrentThread.ManagedThreadId, sum); //使用AsnycState属性获取主线程中传入的同步信号
//释放同步信号表示异步调用已完成
((AutoResetEvent)async.AsyncState).Set(); } staticvoid Main(string[] args)
{
//创建一个委托
Deleg proc =new Deleg(WriteSum); //采用异步方式调用委托
//指定SumDone为异步操作完成后的回调函数
//指定ev为object参数,用于同步回调函数与主线程间操作
IAsyncResult async = proc.BeginInvoke(, , SumDone, ev);
Console.WriteLine("主线程ID号为:{0},异步操作已开始执行,正等待操作完成。", Thread.CurrentThread.ManagedThreadId); //等待异步操作完成
ev.WaitOne();
Console.WriteLine("异步操作已完成!"); System.Console.ReadKey();
}
}
}

  下图是程序的运行结果:

  

  注意观察运行结果,异步方法和回调函数是在同一步线程执行。

为方法指定OneWay特性

  我们可将 System.Runtime.Remoting.Messaging.OneWay特性应用于任何一个方法,该特性告诉CLR该方法不返回任何信息。即 使该方法实际返回了数据(通过return语句或out、ref定义的参数),但只要被标记了OneWay特性,那它就不会再返回任何信息。

  一个被标记为OneWay特性的方法即可以同步方式调用,也可以异步方式调用。如果在它的执行过程中引起了一个异常却没有捕获,在同步方式下,该异常会向上传播;但在异步方式下,该异常将不会被传播。大多数情况下,被标记为OneWay的方法是以异步方式工作。

C#多线程编程之:异步方法调用的更多相关文章

  1. 深入浅出Cocoa多线程编程之 block 与 dispatch quene

    深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...

  2. [Cocoa]深入浅出Cocoa多线程编程之 block 与 dispatch quene

    深入浅出 Cocoa 多线程编程之 block 与 dispatch quene 罗朝辉(http://www.cppblog.com/kesalin CC 许可,转载请注明出处 block 是 Ap ...

  3. iOS多线程编程之NSThread的使用

      目录(?)[-] 简介 iOS有三种多线程编程的技术分别是 三种方式的有缺点介绍 NSThread的使用 NSThread 有两种直接创建方式 参数的意义 PS不显式创建线程的方法 下载图片的例子 ...

  4. iOS多线程编程之NSThread的使用(转)

    本文由http://blog.csdn.net/totogo2010/原创 1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation  ...

  5. [转] iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...

  6. [转] iOS多线程编程之NSOperation和NSOperationQueue的使用

    <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...

  7. [转]iOS多线程编程之NSThread的使用

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...

  8. iOS 多线程编程之Grand Central Dispatch(GCD)

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其它的对称多处理系统的系统.这建立在任务并行运行的线程池模式的基础上的. 它 ...

  9. iOS多线程编程之NSThread的使用(转载)

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1.NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue的 ...

  10. iOS多线程编程之NSOperation和NSOperationQueue的使用

    前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...

随机推荐

  1. JS的 instanceof 方法

    http://www.cnblogs.com/jasonxuli/p/6769282.html 这是 2014-12-10 发在 iteye 上的文章 今天突然想起js的原型继承模型和相关的proto ...

  2. 对OpenCV中seamlessClone的初步实验

    seamlessClone是OpenCV中新出现的函数,应该说如果能够基于较为准确的图像分割,能够得到很好的结果. 原始的前景,背景 三种flag下的融合结果   //注意头文件中添加  #inclu ...

  3. 模块的封装之C语言类的继承和派生

    [交流][微知识]模块的封装(二):C语言的继承和派生 在模块的封装(一):C语言的封装中,我们介绍了如何使用C语言的结构体来实现一个类的封装,并通过掩码结构体的方式实 现了类成员的保护.这一部分,我 ...

  4. 【P4语言学习】Parser解析器

    参考文章:王垠:谈谈Parser 簡單介紹 P4 語言(一)- Parser 什么是Parser 传统的parser,一般出现在编译器和编译原理课程中,援引<谈谈Parser>的定义: 首 ...

  5. MongoDB 默认写入关注保存数据丢失问题与源码简单分析

    MongoDB 默认写入关注可能保存数据丢失问题分析 问题描述: EDI服务进行优化,将原有MQ发送成功并且DB写入成功,两个条件都达成,响应接收订单数据成功,修改为只有有一个条件成功就响应接收数据成 ...

  6. jvm 内存调整

    top查看java占用的内存比较多 top - :: up days, :, user, load average: 0.03, 0.05, 0.05 Tasks: total, running, s ...

  7. Python isspace()方法--转载

    描述 Python isspace() 方法检测字符串是否只由空格组成. 语法 isspace()方法语法: str.isspace() 参数 无. 返回值 如果字符串中只包含空格,则返回 True, ...

  8. C# typeof 与GetType()的区别

    C#中Type类的介绍:https://msdn.microsoft.com/zh-cn/library/system.type(VS.80).aspx C#中任何对象都具有GetType()方法,它 ...

  9. 《WAP》第一次作业:团队亮相

    一.队名:WAP! 二.团队成员组长 组员 : 201571030302/杜有海 201571030327/乌勒扎 201571030304/郝明宇 201571030318/马麒 组长: 20157 ...

  10. 这些HTML、CSS知识点,面试和平时开发都需要 No5-No7(知识点:文字设置、设置背景、数据列表)

    系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5-No7(知识 ...