zoukankan      html  css  js  c++  java
  • 常见异步机制分析

    本章内容:

      1、使用 EndInvoke 等待异步调用

      2、使用 WaitHandle 等待异步调用

      3、轮询状态    轮询异步调用完成

      4、通知机制    异步调用完成时执行回调方法

      异步操作通常用于执行完成时间可能较长的任务,避免阻塞,这是与线程有所相似的地方,具体异同自行百度吧,推荐《多线程与异步的区别》这篇文章,讲得很好,最后总结画龙点睛。“当需要执行I/O操作时,使用异步操作比使用线程+同步I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.Net Remoting等跨进程的调用。
      而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。但是往往由于使用线程编程的简单和符合习惯,所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅,如果需要处理大量的并发操作时就不合适了。”

      

    创建我们使用到的模型和委托

    public delegate string AsyncDele(int callDuration, out int threadId);
    
    //使用异步编程模型 
        public class AsyncDemoModel
        {
            public string TestMethod(int callDuration, out int threadId)
            {
                Console.WriteLine("异步方法开始工作");
                Thread.Sleep(callDuration);
                threadId = Thread.CurrentThread.ManagedThreadId; 
                return "异步方法执行时间 " + callDuration.ToString();
            }
        }

    1、使用 EndInvoke 等待异步调用

       static void Func1()
            {
                AsyncDemoModel ad = new AsyncDemoModel();
                // 创建委托
                AsyncDele dlgt = new AsyncDele(ad.TestMethod);
                // 委托在这里开始异步调用。
                IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
                //人为的线程阻塞。
                Thread.Sleep(1000);
                Console.WriteLine("主线程 {0}开始工作",Thread.CurrentThread.ManagedThreadId);
                // 委托开始EndInvoke调用,这个过程会使主线程等待异步调用完成并返回结果。
                Console.WriteLine("使用 EndInvoke 等待异步调用!!!");
                string ret = dlgt.EndInvoke(out threadId, ar);
                Console.WriteLine("异步线程 {0},返回值 "{1}".", threadId, ret);
                Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
            }

    2、使用 WaitHandle 等待异步调用

     static void Func2()
            {
                AsyncDemoModel ad = new AsyncDemoModel();
                AsyncDele dlgt = new AsyncDele(ad.TestMethod);
                IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
                Thread.Sleep(0);
                Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
                //主线程在这里等待,直到异步线程执行完。
                Console.WriteLine("使用 WaitHandle 等待异步调用!!!");
                ar.AsyncWaitHandle.WaitOne();
                // 和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前
                Console.WriteLine("和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前");
                //在这里做点任何你想作的事。
                //调用EndInvoke获取异步调用的返回结果.
                string ret = dlgt.EndInvoke(out threadId, ar);
                Console.WriteLine("异步线程 {0},返回值 "{1}".", threadId, ret);
                Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
            }

    3、轮询

       static void Func3()
            {
                AsyncDemoModel ad = new AsyncDemoModel();
                AsyncDele dlgt = new AsyncDele(ad.TestMethod);
                IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null);
                Console.WriteLine("使用轮询异步调用!!!");
                Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId);
                //这里每隔10毫秒就检测(轮询)一下异步执行的状态,
                //直到异步调用完成,IsCompleted的值变为ture为止。
                while (ar.IsCompleted == false)
                {
                    Thread.Sleep(10);
                }
                //还是调用一下EndInvoke,来获取返回值。
                string ret = dlgt.EndInvoke(out threadId, ar);
                Console.WriteLine("异步线程 {0},返回值 "{1}".", threadId, ret);
                Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId);
            }

    4、通知机制

     static void Func4()
            {
                AsyncDemoModel ad = new AsyncDemoModel();
                AsyncDele dlgt = new AsyncDele(ad.TestMethod);
                //第三个参数是回调方法。
                //第四个参数可以是任何Object对象,这里它就是
                //执行异步调用的委托本身,把委托本身传递进去的原因在下面可以看到。
                Console.WriteLine("异步调用完成时执行回调!!!");
                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();
            }
    
            //回调函数
            static void CallbackMethod(IAsyncResult ar)
            {
                //在这里,上面那个dlgt作为参数的作用得到了体现,原来它就是为了完成对EndInvoke的调用。
                AsyncDele dlgt = (AsyncDele)ar.AsyncState;
                //通过对EndInvoke的调用获取返回值。
                string ret = dlgt.EndInvoke(out threadId, ar);
                Console.WriteLine("异步线程 {0},返回值 "{1}".", threadId, ret);
            }
  • 相关阅读:
    SQL注入工具大比拼
    黑客知识 彻底堵死SQL注入工具漏洞
    基于jQuery 常用WEB控件收集
    R400安装Windows2003网卡驱动
    预防网站漏洞扫描工具入侵:
    LRU页面置换算法模拟
    Unix编程/应用问答中文版 6./etc/system可调资源限制
    Microsoft uaa bus driver for high definition audio
    UNIX/LINUX 平台可执行文件格式分析
    Modem Device on High Definition Audio Bus
  • 原文地址:https://www.cnblogs.com/EminemJK/p/5828980.html
Copyright © 2011-2022 走看看