C#可以有一个简单易用的机制用于异步执行方法,那就是委托。下面我介绍三种模式,对于这三种模式来说,原始线程都发起了一个异步方法,然后做一些其他处理。然而这些模式不同的是,原始线程获取发起的线程已经完成的消息的方式。

1:在等待一直到完成(wait-nutil-done)模式。

  在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续。

    class Program
{
private delegate int MyDel(int a); public static int MyMenthod(int a)
{
for (int i = 0; i < 1000; i++)
{
a++;
}
return a;
} static void Main(string[] args)
{
var del = new MyDel(MyMenthod);
Console.WriteLine("Before BeginInvoke");
IAsyncResult iar = del.BeginInvoke(5, null, null);
Console.WriteLine("After BeginInvoke"); Console.WriteLine("Doing stuff"); long result = del.EndInvoke(iar); Console.WriteLine("结果为{0}",result);
}
}

  运行结果为

2:轮询模式(polling)。

  原始线程定期检查发起的线程是否完成,如果没有则可以继续做其他的事情。上代码

  class Program
{
private delegate int MyDel(int a); public static int MyMenthod(int a)
{
for (int i = 0; i < 1000; i++)
{
a++;
}
Thread.Sleep(3000);
return a;
} static void Main(string[] args)
{
var del = new MyDel(MyMenthod); IAsyncResult iar = del.BeginInvoke(5,null,null);
Console.WriteLine("After BeginInvoke"); while (!iar.IsCompleted)
{
Console.WriteLine("还没处理完"); Thread.Sleep(2000);
Console.WriteLine("继续处理其他事情");
}
Console.WriteLine("异步执行完成");
long result = del.EndInvoke(iar);
Console.WriteLine("结果为{0}",result);
}
}

  运行结果为:

3:回调模式(callbacl)。

  原始线程一直执行,无需等待或检查发起的线程是否完成,在发起的线程中的引用方法完成之后,发起的线程就会调用回调方法,由回调方法在调用EndInvoke之前处理异步方法的结构。上代码

   class Program
{
private delegate int MyDel(int a); public static int MyMenthod(int a)
{
for (int i = 0; i < 1000; i++)
{
a++;
}
return a;
}
public static void CallBack(IAsyncResult iar)
{
AsyncResult ar = iar as AsyncResult;
MyDel del = (MyDel)ar.AsyncDelegate;
long r = del.EndInvoke(iar);
Thread.Sleep(2000);
Console.WriteLine("结果出来了,为{0}", r);
}
static void Main(string[] args)
{
var del = new MyDel(MyMenthod); Console.WriteLine("After BeginInvoke");
IAsyncResult iar= del.BeginInvoke(5, CallBack, del); Console.WriteLine("Doing More Work In Main");
Thread.Sleep(5000);
}
}

  运行结果为:

回调方法的签名和返回类型必须和AsyncCallbacl委托类型所描述的形式一致。它需要方法接受一个IAsyncResult作为参数并且返回类型是void,如下:

void AsyncCallback(IAsyncResult iar)

我们有多种方式可以为BeginInvoke方法提供回调方法,由于BeginInvoke中的callback参数是AsyncCallback类型的委托,我们可以以委托形式提供,我们也可以只提供回调方法名称,让编译器为我们创建委托,两种形式是等价的。

IAsyncResult iar1 = del.BeginInvoke(5,new AsyncCallback(CallWhenDone),null);

IAsyncResult iar2 = del.BenginInvoke(5,CallWhenDone,null);

C#每天进步一点--异步编程模式的更多相关文章

  1. C#多线程和异步(三)——一些异步编程模式

    一.任务并行库 任务并行库(Task Parallel Library)是BCL中的一个类库,极大地简化了并行编程,Parallel常用的方法有For/ForEach/Invoke三个静态方法.在C# ...

  2. .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)

    本文内容 异步编程类型 异步编程模型(APM) 参考资料 首先澄清,异步编程模式(Asynchronous Programming Patterns)与异步编程模型(Asynchronous Prog ...

  3. C#中的异步编程模式

    异步编程模型(APM) 基于事件的异步编程模式 基于任务的异步模式 Async Await编程 关于C#,可以看看Learning Hard的博客

  4. 二、基于事件的异步编程模式(EAP)

    一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式--APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题--不支持对异步操作的取消和没有提供对进 ...

  5. 基于任务的异步编程模式,Task-based Asynchronous Pattern

    术语: APM           异步编程模型,Asynchronous Programming Model,其中异步操作由一对 Begin/End 方法(如 FileStream.BeginRea ...

  6. [.net 多线程]异步编程模式

    .NET中的异步编程 - EAP/APM 从.NET 4.5开始,支持的三种异步编程模式: 基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern) 异 ...

  7. 基于任务的异步编程模式(TAP)的错误处理

    在前面讲到了<基于任务的异步编程模式(TAP)>,但是如果调用异步方法,没有等待,那么调用异步方法的线程中使用传统的try/catch块是不能捕获到异步方法中的异常.因为在异步方法执行出现 ...

  8. 基于任务的异步编程模式(TAP)

    异步编程是C#5.0的一个重要改进,提供两个关键字:async和await.使用异步编程,方法的调用是在后台运行(通常在线程或任务的帮助下),但不会阻塞调用线程.异步模式分为3种:异步模式.基于事件的 ...

  9. 异步编程(二)基于事件的异步编程模式 (EAP)

    一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式——APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进 ...

随机推荐

  1. 通过一次SpringBoot打成war包部署到tomcat启动总结一般jar包冲突的解决方法

    启动时,报错信息如下: 28-Sep-2018 16:55:41.567 严重 [localhost-startStop-1] org.apache.catalina.core.StandardCon ...

  2. 利用WPF建立自己的3d gis软件(非axhost方式)(四)在地图上添加FrameworkElement

    原文:利用WPF建立自己的3d gis软件(非axhost方式)(四)在地图上添加FrameworkElement 先下载SDK:https://pan.baidu.com/s/1M9kBS6ouUw ...

  3. Sublime Text3中JSX支持Emmet快捷键

    在复习React的过程中,发现Sublime有些快捷键不能用了,如Emmet的Tab快速生成HTML代码只能用Ctrl+E快捷键,而不能用Tab键了,在网上找了很多文章,发现都有问题,最终自己通过下面 ...

  4. PAT 1051-1060 题解

    浏览全部代码:请戳 本文谨代表个人思路,欢迎讨论;) 1051. Pop Sequence (25) 题意 给定 stack 的容量,给定数据的入栈顺序:从 1 开始的正整数序列,在允许随机的出栈操作 ...

  5. JSON.parse(JSON.stringify()) 实现对对象的深度拷贝,从而互不影响

    JSON.parse(JSON.stringify({"key": "value"})) 根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字 ...

  6. Java 9 特性

    Java 8 发布三年多之后,已经于在2017年9月21日发布了. 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新. 这里有九个令人兴奋的新功能. 1. Java 平台级 ...

  7. expdp&amp;impdp

    1 创建逻辑文件夹,该命令不会在操作系统创建真正的文件夹,最好以system等管理员创建.  create directory dpdata1 as '/opt/oracle/dpdata1';  c ...

  8. java中用反射访问私有方法和私有成员[转]

    转自: http://zhouyangchenrui.iteye.com/blog/470521 java的反射可以绕过访问权限,访问到类的私有方法和成员.可能这点会引起安全性的讨论.反射的使用帮助解 ...

  9. HistCite 引文分析软件的利器

    所需工具及网站清单, HISTCITE:DOWNLOAD YOUR FREE COPY. 提交自己的基本信息即可,十分简单: SCI数据库官网(web of science):http://apps. ...

  10. 零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果

    原文:零元学Expression Design 4 - Chapter 6 教你如何在5分钟内做出文字立体感效果 又来一篇五分钟做设计啦~ 本篇将教大家如何运用Design内建工具Blend Path ...