先推荐阅读下面的资料:

MSDN:异步编程设计模式

IBM developerworks: 使用异步 I/O 大大提高应用程序的性能

参考博文:

1、正确使用异步操作

2、Lab:体会ASP.NET异步处理请求的效果

3、WCF中的异步调用

4、WCF从理论到实践(11)-异步

5、异步编程

.NET Framework 为异步操作提供两种设计模式:
1、使用 IAsyncResult 对象的异步操作。
2、使用事件的异步操作。

IAsyncResult接口类型

    [ComVisible(true)]
    public interface IAsyncResult
    {
        // 摘要:
        //     获取用户定义的对象,它限定或包含关于异步操作的信息。
        //
        // 返回结果:
        //     用户定义的对象,它限定或包含关于异步操作的信息。
        object AsyncState { get; }
        //
        // 摘要:
        //     获取用于等待异步操作完成的 System.Threading.WaitHandle。
        //
        // 返回结果:
        //     用于等待异步操作完成的 System.Threading.WaitHandle。
        WaitHandle AsyncWaitHandle { get; }
        //
        // 摘要:
        //     获取异步操作是否同步完成的指示。
        //
        // 返回结果:
        //     如果异步操作同步完成,则为 true;否则为 false。
        bool CompletedSynchronously { get; }
        //
        // 摘要:
        //     获取异步操作是否已完成的指示。
        //
        // 返回结果:
        //     如果操作完成则为 true,否则为 false。
        bool IsCompleted { get; }
    }

下面是使用 IAsyncResult 对象的测试代码。

 public delegate string AsyncDelegate(int callDuration, out int threadId);
    class Program
    {
        static void Main(string[] args)
        {
            Fun1();
            Console.ReadLine();
        }

private static int threadId;

//阻塞等待   使用 EndInvoke 等待异步调用  
        static void Fun1()
        {
            //创建示例类的实例。
            AsyncDemo ad = new AsyncDemo();
            // 创建委托
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            // 委托在这里开始异步调用。
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            //人为的线程阻塞。
            Thread.Sleep(0);
            Console.WriteLine("主线程 {0}开始工作",Thread.CurrentThread.ManagedThreadId);
            // 委托开始EndInvoke调用,这个过程会使主线程等待异步调用完成并返回结果。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
        }
        
        //阻塞等待  使用 WaitHandle 等待异步调用
        static void Fun2()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            Thread.Sleep(0);
            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
            //主线程在这里等待,直到异步线程执行完。
            ar.AsyncWaitHandle.WaitOne();
            // 和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前
            //在这里做点任何你想作的事。
            //调用EndInvoke获取异步调用的返回结果.
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
        }

//轮询状态    轮询异步调用完成
        static void Fun3()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
            //这里每隔10毫秒就检测(轮询)一下异步执行的状态,
            //直到异步调用完成,IsCompleted的值变为ture为止。
            while (ar.IsCompleted == false)
            {
                Thread.Sleep(10);
            }

//还记得微软的那个善意的提醒吗?虽然IsCompleted为true了,
            //我们还是调用一下EndInvoke,来获取返回值。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
            Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
        }

//通知机制    异步调用完成时执行回调方法
        static void Fun4()
        {
            AsyncDemo ad = new AsyncDemo();
            AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
            //注意第三个参数,这就是我们要用到的回调方法。
            //第四个参数更为有趣,它可以是任何Object对象,这里它就是
            //执行异步调用的委托本身,把委托本身传递进去的原因在下面可以看到。
            Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
            IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, new AsyncCallback(CallbackMethod), dlgt);
            Console.WriteLine("主线程 {0}结束工作", Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();
        }
        //回调函数必须严格的遵照AsyncCallback委托的签名。
        static void CallbackMethod(IAsyncResult ar)
        {
            //在这里,上面那个dlgt作为参数的作用得到了体现,原来它就是为了完成对EndInvoke的调用啊。
            AsyncDelegate dlgt = (AsyncDelegate)ar.AsyncState;
            //通过对EndInvoke的调用获取返回值。
            string ret = dlgt.EndInvoke(out threadId, ar);
            Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret);
        }
    }
    //使用异步编程模型 
    public class AsyncDemo
    {
        public string TestMethod(int callDuration, out int threadId)
        {
            Console.WriteLine("异步方法开始工作");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId; 
            return "异步方法执行时间 " + callDuration.ToString();
        }
    }

执行结果:

Fun1--------------------

异步方法开始工作
主线程 10开始工作
异步线程 7,返回值 "异步方法执行时间 5000".
主线程10结束工作
Fun2---------------------
异步方法开始工作
主线程 10开始工作
异步线程 7,返回值 "异步方法执行时间 5000".
主线程10结束工作
Fun3---------------------

主线程 10开始工作
异步方法开始工作
异步线程 7,返回值 "异步方法执行时间 5000".
主线程10结束工作
Fun4---------------------
主线程 10开始工作
主线程 10结束工作
异步方法开始工作
异步线程 7,返回值 "异步方法执行时间 5000".
--------------------------

工作当中有一个调用ActiveMQ的产品,每天大概是上万的消息。压力也不是很大。最近总是出现调用MQ阻塞的情况。负责MQ的同事也没有找到原因。

我是想寻找一个消息队列的代替品。 上面的第四个方法,异步线程不阻塞调用线程,当然调用线程也无需处理调用结果,貌似可以作为一个代替方案。

转载于:https://www.cnblogs.com/tenghoo/archive/2010/01/07/ARM_IAsyncResult.html

异步编程模型--使用 IAsyncResult 对象相关推荐

  1. 【转】1.6异步编程:IAsyncResult异步编程模型 (APM)

    传送门:异步编程系列目录-- 大部分开发人员,在开发多线程应用程序时,都是使用ThreadPool的QueueUserWorkItem方法来发起一次简单的异步操作.然而,这个技术存在许多限制.最大的问 ...

  2. c# 三种异步编程模型EAP(*)、 APM(*)和 TPL

    为什么80%的码农都做不了架构师?>>>    EAP 是 Event-based Asynchronous Pattern(基于事件的异步模型)的简写 优点是简单,缺点是当实现复杂 ...

  3. 简单地使用线程之一:使用异步编程模型

    .NetFramework的异步编程模型从本质上来说是使用线程池来完成异步的任务,异步委托.HttpWebRequest等都使用了异步模型. 这里我们使用异步委托来说明异步编程模型. 首先,我们来明确 ...

  4. [你必须知道的异步编程]——异步编程模型(APM)

    本专题概要: 引言 你知道APM吗? 你想知道如何使用异步编程模型编写代码吗? 使用委托也可以实现异步编程,你知道否? 小结 一.引言 在前面的C#基础知识系列中介绍了从C#1.0--C#4.0中一些 ...

  5. 【转】谈谈c#中异步编程模型的变迁**

    大家在编程过程中都会用到一些异步编程的情况.在c#的BCL中,很多api都提供了异步方法,初学者可能对各种不同异步方法的使用感到迷惑,本文主要为大家梳理一下异步方法的变迁以及如何使用异步方法. Beg ...

  6. 【转】异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

    最近我为大家陆续介绍了"IAsyncResult异步编程模型 (APM)"和"基于事件的异步编程模式(EAP)"两种异步编程模型.在.NET4.0 中Micro ...

  7. 【转】1.8异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

    传送门:异步编程系列目录-- 最近我为大家陆续介绍了"IAsyncResult异步编程模型 (APM)"和"基于事件的异步编程模式(EAP)"两种异步编程模型. ...

  8. C#异步编程-------异步编程模型(APM)

    术语解释: APM               异步编程模型, Asynchronous Programming Model EAP                基于事件的异步编程模式, Event ...

  9. 异步编程模型(C#5.0系列)

    关于C#5.0的新功能--async和await关键字.它们是语法糖,可以简化异步操作代码的构造.当C#编译器看到一个await表达式时,它会生成代码,该代码自动异步地调用该表达式,然后立即将控制流返 ...

最新文章

  1. 通用Windows应用《博客园-开发者的网上家园》开发(1)——MVVM模式
  2. 《Windows via C/C++》学习笔记 —— Windows 线程池
  3. Grid布局和Flex布局
  4. TensorFlow发布全新版本,又会带来哪些变革?
  5. [react] 请描述下事件在react中的处理方式是什么?
  6. MySQL innosetup_jdk,tomcat,mysql,innosetup封装
  7. SpringMVC 通过post接收form参数或者json参数
  8. Python操作文件文档
  9. 判断ip地址的合法性python_使用Python判断IP地址合法性的方法实例
  10. 使用volatile关键字的场景
  11. Ubuntu下安装Oracle Instant Client
  12. 极简算法 —— 判断两字符串是否为相同字母的不同顺序组成
  13. python fund_Python fund-my-watcard包_程序模块 - PyPI - Python中文网
  14. JavaScript内建对象
  15. WPS文档批量转换成PDF
  16. 【docker 安装-环境初始化】
  17. phpRedis函数使用总结
  18. java中的math.abs_java – Math.abs(a – b)的更快实现 – Math.abs(c – d)?
  19. 交行信用卡总经理王卫东:信用卡互联网转型有五大基础
  20. Ubuntu零基础教学-GParted磁盘分区工具使用|超级详细,手把手教学

热门文章

  1. 拨测工具_您可以拨多少钱? 快速简单地介绍有用的工具。
  2. im和音视频开发哪个更好_如何阅读成为更好的开发者的方式
  3. Hadoop集群搭建(六:HBase的安装配置)
  4. Java怎么定义图片公共路径_【Java】springboot配置图片访问路径
  5. 如何理解分时系统的四个特征
  6. 9.spark core之共享变量
  7. 【跃迁之路】【425天】刻意练习系列184—SQL(2018.04.06)
  8. linux 在执行命令过程中,反单引号(`)这个符号代表的意义为何?
  9. 【spring框架】spring整合hibernate初步
  10. PL/SQL程序设计 第七章 包的创建和应用