首先来看一个简单的例子:

  1. 小明在烧水,等水烧开以后,将开水灌入热水瓶,然后开始整理家务
  2. 小文在烧水,在烧水的过程中整理家务,等水烧开以后,放下手中的家务活,将开水灌入热水瓶,然后继续整理家务

这也是日常生活中很常见的情形,小文的办事效率明显要高于小明。从C#程序执行的角度考虑,小明使用的同步处理方式,而小文则使用的异步处理方式。

同步处理方式下,事务是按顺序一件一件处理的;而异步方式则是,将子操作从主操作中分离出来,主操作继续进行,子操作在完成处理的时候通知主操作。

在C#中,异步通过委托来完成。请看下面的例子:

  1. class Program
  2. {
  3. static TimeSpan Boil()
  4. {
  5. Console.WriteLine("水壶:开始烧水...");
  6. Thread.Sleep(6000);
  7. Console.WriteLine("水壶:水已经烧开了!");
  8. return TimeSpan.MinValue;
  9. }
  10. delegate TimeSpan BoilingDelegate();
  11. static void Main(string[] args)
  12. {
  13. Console.WriteLine("小文:将水壶放在炉子上");
  14. BoilingDelegate d = new BoilingDelegate(Boil);
  15. IAsyncResult result = d.BeginInvoke(BoilingFinishedCallback, null);
  16. Console.WriteLine("小文:开始整理家务...");
  17. for (int i = 0; i < 20; i++)
  18. {
  19. Console.WriteLine("小文:整理第{0}项家务...", i + 1);
  20. Thread.Sleep(1000);
  21. }
  22. }
  23. static void BoilingFinishedCallback(IAsyncResult result)
  24. {
  25. AsyncResult asyncResult = (AsyncResult)result;
  26. BoilingDelegate del = (BoilingDelegate)asyncResult.AsyncDelegate;
  27. del.EndInvoke(result);
  28. Console.WriteLine("小文:将热水灌到热水瓶");
  29. Console.WriteLine("小文:继续整理家务");
  30. }
  31. }

上面的例子是一个最简单的异步调用的例子,没有对异步调用函数做任何参数传递以及返回值校验。这个例子反映了小文烧水的流程,首先小文将水壶放在炉子上,在定义好委托以后,就使用BeginInvoke方法开始异步调用,即让水壶开始烧水,于是小文便开始整理家务。水烧开后,C#的异步模型会触发由BeginInvoke方法所指定的回调函数,也就是水烧开后的处理逻辑由这个回调函数定义,此时小文将水灌入热水瓶并继续整理家务。

由此可见,在C#中实现异步调用其实并不复杂,首先创建一个异步处理函数,并针对其定义一个委托;然后在调用函数的时候,使用委托的BeginInvoke方法,指定在函数处理完成时的回调函数(如果不需要对完成事件做处理,可以给null值),并指定所需的参数(如果没有参数,也可以给null值);最后在回调函数中处理完成事件。

请注意上例回调函数中的EndInvoke调用,EndInvoke会使得调用线程阻塞,直到异步函数处理完成。显然,紧接在BeginInvoke后面的EndInvoke使用方式与同步调用等价。

EndInvoke调用的返回值也就是异步处理函数的返回值。我们把程序稍作修改,将Boil方法改成下面的形式:

  1. static TimeSpan Boil()
  2. {
  3. DateTime begin = DateTime.Now;
  4. Console.WriteLine("水壶:开始烧水...");
  5. Thread.Sleep(6000);
  6. Console.WriteLine("水壶:水已经烧开了!");
  7. return DateTime.Now - begin;
  8. }

然后将BoilingFinishedCallback改成下面的形式:

  1. static void BoilingFinishedCallback(IAsyncResult result)
  2. {
  3. AsyncResult asyncResult = (AsyncResult)result;
  4. BoilingDelegate del = (BoilingDelegate)asyncResult.AsyncDelegate;
  5. Console.WriteLine("(烧水一共用去{0}时间)", del.EndInvoke(result));
  6. Console.WriteLine("小文:将热水灌到热水瓶");
  7. Console.WriteLine("小文:继续整理家务");
  8. }

那么我们就可以在EndInvoke的时候,获得由Boil异步处理函数返回的时间值。事实上,如果定义的BoilingDelegate委托存在参数列表,那么我们也可以在BeginInvoke的时候,将所需的参数传给异步处理函数。BeginInvoke/EndInvoke函数的签名与定义它们的委托签名有关。

c# 异步调用简单例子(转载)的更多相关文章

  1. 用Html5/CSS3做Winform,一步一步教你搭建CefSharp开发环境(附JavaScript异步调用C#例子,及全部源代码)上

    本文为鸡毛巾原创,原文地址:http://www.cnblogs.com/jimaojin/p/7077131.html,转载请注明 CefSharp说白了就是Chromium浏览器的嵌入式核心,我们 ...

  2. 使用 CXF 做 webservice 简单例子(转载)

    使用 CXF 做 webservice 简单例子     Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构.它允许创建高性能和可扩展的服务,您可以将这 ...

  3. 【IOS】异步调用--- 简单使用记录

    /×× ×实现功能:店铺被删除后,先显示提示toast.然后,页面休眠5秒后,再返回到店铺列表页面.×/ - (void)processDeleteShopError { _isLoadingData ...

  4. 【Python】Async异步等待简单例子理解

    import time def run(coroutine): try: print("") coroutine.send(None) except StopIteration a ...

  5. c#异步调用

    首先来看一个简单的例子: 小明在烧水,等水烧开以后,将开水灌入热水瓶,然后开始整理家务 小文在烧水,在烧水的过程中整理家务,等水烧开以后,放下手中的家务活,将开水灌入热水瓶,然后继续整理家务 这也是日 ...

  6. C#基础:异步调用 【转】

    首先来看一个简单的例子: 小明在烧水,等水烧开以后,将开水灌入热水瓶,然后开始整理家务 小文在烧水,在烧水的过程中整理家务,等水烧开以后,放下手中的家务活,将开水灌入热水瓶,然后继续整理家务 这也是日 ...

  7. 使用Promise解决多层异步调用的简单学习【转】

    前言 本文章转载文章: https://www.jianshu.com/p/29da9aef4c1c 第一次接触到Promise这个东西,是2012年微软发布Windows8操作系统后抱着作死好奇的心 ...

  8. 一个简单的webservice的demo(下)winform异步调用webservice

    绕了一大圈,又开始接触winform的项目来了,虽然很小吧.写一个winform的异步调用webservice的demo,还是简单的. 一个简单的Webservice的demo,简单模拟服务 一个简单 ...

  9. 循序渐进做项目系列(2):最简单的C/S程序——消息异步调用与消息同步调用

    上篇博客 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法 实现了一个最简单的C/S程序,即让服务器来做加法.当时为了通俗易懂采用了消息异步调用的方式.今天我们要采用消息同步调用的方式 ...

随机推荐

  1. windows2008无线网卡和.net3.5安装

    今天在联想T420S笔记本上安装windows2008标准版,安装完成后部分驱动软件不能安装,要求.net framework3.5,下载.net3.5安装时提示应该用角色管理器安装. 根据提示打开服 ...

  2. IOS开发几何类方法 CGGeometry.h文件

    CGGeometry.h文件是用C语言实现的一个封装了许多常用几何方法的文件. 一.几个常用结构体 struct CGPoint { CGFloat x; CGFloat y; }; 定义一个点,设置 ...

  3. 转: 向tabControl中添加一个Form(C#)

  4. AnyWhere

    anyexec_date 201506171258 anyexec_date @@AnyWhereCmd idc python /home/appadmin/nicker/tools/QUI.py m ...

  5. c#POST请求和接收post请求

    c# post请求发送数据 /// <summary> /// POST请求 /// </summary> /// <param name="url" ...

  6. [WPF]ListView点击列头排序功能实现

    [转]   [WPF]ListView点击列头排序功能实现 这是一个非常常见的功能,要求也很简单,在Column Header上显示一个小三角表示表示现在是在哪个Header上的正序还是倒序就可以了. ...

  7. 前端MVVM学习之KnockOut(二)

    现在开始学习Knockout并且做个简单的例子. Knockout是建立在以下三个核心功能之上的: 1.Observables and dependency tracking(属性监控与依赖跟踪) 2 ...

  8. grep搜索当前目录和递归搜索子目录中文本文件的特定pattern

    一般在windows上文本编辑器notepad++,UE这些都有这些功能,Linux下就换了一种方式,用grep来完成文件中信息查找的方式. grep -R -n --include="*. ...

  9. synchronized常见用法解析及示例

    synchronized作用:保证代码执行的原子性:保证可见性(与volatile作用相同) JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法 ...

  10. 转:LINQ查询返回DataTable类型

    动态绑定ReportViewer虽然之前实现过,但现在弄起来还是有点晕,主要是过去没有使用Linq,数据的操作经常用到DataTable,可以直接拿来使用,现在用Linq更方便,也懒得再用之前的数据库 ...