最近很忙,既要外出找工作又要兼顾老板公司的项目。今天在公司,忙里偷闲,总结一下.NET中的异步调用函数的实现方法,DebugLZQ在写这篇博文之前自己先动手写了本文的所有示例代码,开写之前是做过功课的,用代码说话方有说服力。

  本文的内容旨在用最简洁的代码来把异步调用的方法说清楚,园子里的高手老鸟可以绕行,不喜勿喷,非诚勿扰~

  lz的前一篇文章简单的说了下异步,主要是从理解上来讲;这篇文章主要写具体的实现方法。实现异步编程有4种方法可供选择,这4种访求实际上也对应着4种异步调用的模式,分为“等待”和“回调”两大类。四种方法,我在代码中都进行了详细的注释,这里不罗嗦了,直接用代码说明吧

第一种方法:BeginEnvoke EndEnvoke方法,属于“等待”类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace 异步调用实现方法汇总
{/// <summary>/// 异步调用方法总结:/// 1.BeginEnvoke EndEnvoke/// 当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕/// </summary>class Program{public delegate void PrintDelegate(string s);static void Main(string[] args){PrintDelegate printDelegate = Print;Console.WriteLine("主线程");IAsyncResult result= printDelegate.BeginInvoke("Hello World.", null, null);Console.WriteLine("主线程继续执行...");//当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕
            printDelegate.EndInvoke(result);Console.WriteLine("Press any key to continue...");Console.ReadKey(true);}public static void Print(string s){Console.WriteLine("异步线程开始执行:"+s);Thread.Sleep(5000);}}
}

需要注意的地方,代码中都有注明了,程序运行结果如下:

第二种方法:WaitOne。同样属于“等待”类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace 异步调用实现方法汇总2
{/// <summary>/// 异步调用方法总结:/// 2.WaitOne/// 可以看到,与EndInvoke类似,只是用WaitOne函数代码了EndInvoke而已。/// </summary>class Program{public delegate void PrintDelegate(string s);static void Main(string[] args){PrintDelegate printDelegate = Print;Console.WriteLine("主线程");IAsyncResult result = printDelegate.BeginInvoke("Hello World.", null, null);Console.WriteLine("主线程继续执行...");result.AsyncWaitHandle.WaitOne(-1, false);Console.WriteLine("Press any key to continue...");Console.ReadKey(true);}public static void Print(string s){Console.WriteLine("异步线程开始执行:" + s);Thread.Sleep(5000);}}
}

需要注意的地方,代码中都有注明了,程序运行结果如下:

第三种方法:轮询。也是属于“等待”类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace 异步调用实现方法汇总3
{/// <summary>/// 异步调用方法总结:/// 3.轮询/// 之前提到的两种方法,只能等下异步方法执行完毕,/// 在完毕之前没有任何提示信息,整个程序就像没有响应一样,用户体验不好,/// 可以通过检查IasyncResult类型的IsCompleted属性来检查异步调用是否完成,/// 如果没有完成,则可以适时地显示一些提示信息/// </summary>class Program{public delegate void PrintDelegate(string s);static void Main(string[] args){PrintDelegate printDelegate = Print;Console.WriteLine("主线程:"+Thread.CurrentThread.ManagedThreadId );IAsyncResult result = printDelegate.BeginInvoke("Hello world.", null, null);Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId + ",继续执行...");while (!result.IsCompleted){Console.WriteLine(".");Thread.Sleep(500);}Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId + "  Press any key to continue...");Console.ReadKey(true);}public static void Print(string s){Console.WriteLine("当前线程:" + Thread.CurrentThread.ManagedThreadId + s);Thread.Sleep(5000);}}
}

需要注意的地方,代码中都有注明了,程序运行结果如下:

第四种方法:回调。当然属于“回调”类。推荐!!!!

  之前三种方法者在等待异步方法执行完毕后才能拿到执行的结果,期间主线程均处于等待状态。回调和它们最大的区别是,在调用BeginInvoke时只要提供了回调方法,那么主线程就不必要再等待异步线程工作完毕,异步线程在工作结束后会主动调用我们提供的回调方法,并在回调方法中做相应的处理。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace 异步调用实现方法汇总4
{/// <summary>/// 异步调用方法总结:/// 4.回调/// 之前三种方法者在等待异步方法执行完毕后才能拿到执行的结果,期间主线程均处于等待状态。/// 回调和它们最大的区别是,在调用BeginInvoke时只要提供了回调方法,那么主线程就不必要再等待异步线程工作完毕,/// 异步线程在工作结束后会主动调用我们提供的回调方法,并在回调方法中做相应的处理,例如显示异步调用的结果。/// </summary>class Program{public delegate void PrintDelegate(string s);static void Main(string[] args){PrintDelegate printDelegate = Print;Console.WriteLine("主线程.");printDelegate.BeginInvoke("Hello world.", PrintComeplete, printDelegate);Console.WriteLine("主线程继续执行...");Console.WriteLine("Press any key to continue...");Console.ReadKey(true);}public static void Print(string s){ Console.WriteLine("当前线程:"+s);Thread.Sleep(5000);}//回调方法要求//1.返回类型为void//2.只有一个参数IAsyncResultpublic static void PrintComeplete(IAsyncResult result){(result.AsyncState as PrintDelegate).EndInvoke(result);Console.WriteLine("当前线程结束." + result.AsyncState.ToString());}}
}

需要注意的地方,代码中都有注明了,程序运行结果如下:

通过EndInvoke方法得到同步函数的返回值。上面的同步方法返回值为void,我们给个例子:

using System.Diagnostics;
using System.Threading;
using System.Windows;namespace TestDelegateWrapper
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void ButtonBase_OnClick(object sender, RoutedEventArgs e){WrapperSyncMethodAsync("ABC");Trace.WriteLine("Main thread continue...");}private delegate string SyncMethod1Delegate(string str);private void WrapperSyncMethodAsync(string str){SyncMethod1Delegate syncMethod1Delegate = SyncMethod1;syncMethod1Delegate.BeginInvoke(str, x =>{var result= syncMethod1Delegate.EndInvoke(x);// using the result to do something
                Trace.WriteLine(result);}, null);}private string SyncMethod1(string str){Thread.Sleep(2000);return str;}}
}

输出如下:

Main thread continue...
ABC

以上就是四种实现异步调用函数的四种方法,说的很清楚了,就写这么多~

reference:.NET Framework Delegates: Understanding Asynchronous Delegates

DebugLZQ后续之作:从C#5.0说起:再次总结C#异步调用方法发展史 

大家都不是牛人,多多学习,多多交流【请点击下面的“绿色通道”---“关注DebugLZQ”,共同交流进步~】

转载于:https://www.cnblogs.com/DebugLZQ/archive/2012/11/02/2751272.html

.NET异步编程总结----四种实现模式相关推荐

  1. (转)javascript异步编程的四种方法

    本文转自:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 作者:阮一峰 本文仅仅作为个人mark ...

  2. JavaScript异步编程的四种方法(转)

    作者: 阮一峰 日期: 2012年12月21日 你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是 ...

  3. C# 使用委托实现异步编程的四种方式

    一.关于委托 1.委托概念:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递 个人角色这个概念有些晦涩难懂,大家可以把委托当成一个方法的指针就好了,可以指向一个方法.或者 ...

  4. JS 异步编程的 5 种解决方案

    我们知道 JS 语言的执行环境是"单线程",所谓"单线程",就是指一次只能完成一件任务,这种模式的好处是实现起来比较简单,执行环境相对单纯:坏处是只要有一个任务 ...

  5. 【C++】多线程与异步编程【四】

    文章目录 [C++]多线程与异步编程[四] 0.三问 1.什么是异步编程? 1.1同步与异步 1.2 **阻塞与非阻塞** 2.如何使用异步编程 2.1 使用全局变量与条件变量传递结果 实例1: 2. ...

  6. Android学习-Kotlin语言入门-变量、函数、语法糖、when、for-in、主构造函数、单例类、函数式API、集合遍历、隐式Intent、Activity生命周期、四种启动模式、标准函数

    探究java语言的运行机制 变量.函数.语法糖 when条件语句 for循环 主构造函数.次构造函数 数据类和单例类 集合的创建与遍历 集合的函数式API 创建菜单 隐式使用Intent Activi ...

  7. 什么是云计算、云计算的特点、三种服务模式、四种部署模式

    什么是云计算? 云计算是一种技术架构,随着当前技术的发展,应用提供商需要处理的计算量越来越大,意味着应用提供商需要扩充自己的服务器.存储等一系列设备来支撑自己的服务,成本也随之上升.于是,云计算的概念 ...

  8. PHP的四种运行模式

    PHP的四种运行模式 1.CGI 2.FAST-CGI 3.CLI 4.模块模式(Apache等web服务器运行的模块模式) 一.CGI(Common Gateway Interface) CGI即通 ...

  9. 零基础学习SpringSecurity OAuth2 四种授权模式(理论+实战)(配套视频讲解)

    配套视频直达 背景 前段时间有同学私信我,让我讲下Oauth2授权模式,并且还强调是零基础的那种,我也不太理解这个零基础到底是什么程度,但是我觉得任何阶段的同学看完我这个视频,对OAuth2的理解将会 ...

最新文章

  1. OpenCV ASIFT的实例(附完整代码)
  2. 统计csv词频_基于给定词语列表统计词频
  3. C# 10 新特性 —— CallerArgumentExpression
  4. Thread.join(), CountDownLatch、CyclicBarrier和 Semaphore区别,联系及应用
  5. sklearn-preprocessing预处理数据的方法
  6. vim写python_用 Vim 写 Python 的最佳实践
  7. java匹配字符串所在位置_Java:获取字符串中匹配项位置的方法?
  8. android布局--Android fill_parent、wrap_content和match_parent的区别
  9. 《HTML CSS设计与构建网站》书评之-异类的风格,不一样的效果
  10. 计算机科学与技术专业的论文周报,毕业设计(实习)周报
  11. 生成对抗网络(十)----------infoGAN
  12. Logback文件详解
  13. python解决写入文件乱码问题
  14. 记录自己需要读的几本书
  15. Hash——哈希法概念、哈希函数构造方法、哈希冲突解决办法(重点讨论链地址法)
  16. 爱普生Epson LQ-680K 打印机驱动
  17. 笔记本安装固态涉及到的注意事项
  18. PHP单例模式 构造方法
  19. css 多文件上传框美化
  20. 怎么截取视频片段?截取视频片段其实很好操作

热门文章

  1. opencv 显示程序运行时间
  2. [paper reading] YOLO v1
  3. Horizo​​ntal Pod Autoscaler (HPA) 根据资源横向扩展
  4. matlab2c使用c++实现matlab函数系列教程-mean函数
  5. jQuery Mobile中按钮<a>或<button>添加class样式ui-btn-*
  6. jquery属性过滤选择器[attr=value]、[attr!=value]、[attr^=value]、[attr$=value]、[attr*=value]、[attr|=value]
  7. MySQL(四)InnoDB中一棵B+树能存多少行数据
  8. User Profile的名称和显示名称
  9. RHEL7忘记密码:修改root密码
  10. openlayers5学习笔记-001