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

  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. PHP学习笔记十九【析构函数】

    <?php class Person{ public $name; public $age; public function __construct($iname,$iage) { $this- ...

  2. Windows Phone 学习教程(一)

    http://www.cnblogs.com/webabcd/category/385852.html Windows Phone 7 教程 Windows Phone 8.1 Windows Pho ...

  3. 返回某个界面——nav

     NSInteger index=[[self.navigationController viewControllers]indexOfObject:self];  [self.navigationC ...

  4. 通过XSLT转换XML

    Hello,every body.又与大家见面了,哈哈.今天我与大家分享一下XSLT,XSL,XML,XPath.因为项目中有些功能用到了XSLT.XML等技术.所以今天好好研究了一下这几个方面的技术 ...

  5. Python学习笔记3(数据结构)

    1.元组结构(Tuple) 元组由不同的元素组成,每个元素可以存储不同类型的数据,如字符串.数字甚至元组.元组创建后不能修改. 元组通常代表一行数据,而元组中的元素代表不同的数据项. 1.1元组的创建 ...

  6. (转) Class

    Classes are an expanded concept of data structures: like data structures, they can contain data memb ...

  7. sqlsever连接两个不同服务器上的数据库进行查询

    exec sp_addlinkedserver 'LocalSERVER' ,--别名,自己起一个 '' , 'SQLOLEDB' , 'ip' --远程服务器地址 exec sp_addlinked ...

  8. js阻止元素的默认事件与冒泡事件

    嵌套的div元素,如果父级和子元素都绑定了一些事件,那么在点击最内层子元素时可能会触发父级元素的事件,从而带来一定的影响. 1. event.preventDefault();  -- 阻止元素的默认 ...

  9. PMBOK 项目管理 九大知识领域和五大流程 PMI

    Project Management Institute.PMI 是世界上最大的非盈利机构,是项目管理领域的领导者.PMI制定项目管理行业标准,带领项目管理的研究并提供项目管理的培训,证书,还有一些加 ...

  10. Linux命令之xargs的分析及隐患

    写一个main.c: #include <stdio.h> int main(){ printf("foo"); printf("bar"); re ...