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

  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. 使用HttpClient发送GET请求

    HttpRequestMessage http_req_msg = new HttpRequestMessage(); http_req_msg.Method = HttpMethod.Get; ht ...

  2. Vim知识点收集

    (注意: 只记录工作中实际使用的命令) 删除带有pattern的所有行    :g/pattern/d 删除不带pattern的所有行   :g!/pattern/d 匹配red和blue,无次序   ...

  3. web前端中实现多标签页切换的效果

    在这里,实现多标签页效果的方法有两个,一个是基于DOM的,另一个是基于jquery的,此次我写的是一个对于一个电话套餐的不同,显示不同的标签页 方法一: 首先,我们要把页面的大体框架和样式写出来,ht ...

  4. Struts2中的ActionContext

    ActionContext(Action上下文) ActionContext介绍 通过上面用户注册例子的学习,我们知道Xwork与Web无关性,我们的Action不用去依赖于任何Web容器,不用和那些 ...

  5. windows在文件夹快速打开命令行

    普通打开方式 按住shift键,在指定的文件夹上右键,会发现有"在此处打开命令行窗口"的字样,选择该项,即可打开命令行,并且路径刚好是你刚才选择的文件夹路径 管理员方式打开 修改注 ...

  6. 使用myfocus制作焦点图

    第一步:引入myfocus基本库和所要使用样式的js和css文件 <script src="js/myfocus-2.0.1.min.js"></script&g ...

  7. MySQL数据库SQL层级优化

    本篇主涉及MySQL SQL Statements层面的优化. 首先,推荐一个链接为万物之始:http://dev.mysql.com/doc/refman/5.0/en/optimization.h ...

  8. Hello Word!

    第一次来博客园,作为技术的基站,多余的话不说了,就一个helloword! <script type="text/javascript"> //等待dom元素加载完毕. ...

  9. Python 之socket的应用

    本节主要讲解socket编程的有关知识点,顺便也会讲解一些其它的关联性知识: 一.概述(socket.socketserver): python对于socket编程,提供了两个模块,分别是socket ...

  10. NET Core的知识

    NET Core的基础知识补遗 阅读目录 前言 在.NET Core之前 在.NET Core起步 .NET Core 1.0 .NET平台 开发环境 FAQ 写在最后 回到目录 前言 .NET Co ...