zoukankan      html  css  js  c++  java
  • c# 异步调用简单例子(转载)

    一、.net 2.0 以下的例子

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

    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.   
    11.     delegate TimeSpan BoilingDelegate();   
    12.   
    13.     static void Main(string[] args)   
    14.     {   
    15.         Console.WriteLine("小文:将水壶放在炉子上");   
    16.         BoilingDelegate d = new BoilingDelegate(Boil);   
    17.         IAsyncResult result = d.BeginInvoke(BoilingFinishedCallback, null);   
    18.         Console.WriteLine("小文:开始整理家务...");   
    19.         for (int i = 0; i < 20; i++)   
    20.         {   
    21.             Console.WriteLine("小文:整理第{0}项家务...", i + 1);   
    22.             Thread.Sleep(1000);   
    23.         }   
    24.     }   
    25.   
    26.     static void BoilingFinishedCallback(IAsyncResult result)   
    27.     {   
    28.         AsyncResult asyncResult = (AsyncResult)result;   
    29.         BoilingDelegate del = (BoilingDelegate)asyncResult.AsyncDelegate;
    30.         del.EndInvoke(result);
    31.         Console.WriteLine("小文:将热水灌到热水瓶");   
    32.         Console.WriteLine("小文:继续整理家务");   
    33.            
    34.     }   
    35. }  

    上面的例子是一个最简单的异步调用的例子,没有对异步调用函数做任何参数传递以及返回值校验。这个例子反映了小文烧水的流程,首先小文将水壶放在炉子上,在定义好委托以后,就使用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函数的签名与定义它们的委托签名有关。

    二、.net 2.0 以上的例子

    Console.WriteLine("小文:把水壶放到炉子上");
                    Thread ta = new Thread(new ThreadStart(delegate()
                    {
                        DateTime dt = DateTime.Now;
                        Console.WriteLine("水壶:开始烧水...");
                        Thread.Sleep(6000);
                        Console.WriteLine("水壶:水已经烧开了!");
    
                        Console.WriteLine("烧水一共用了{0}时间。", DateTime.Now - dt);
                        Console.WriteLine("小文:将热水灌到热水瓶");
                        Console.WriteLine("小文:继续整理家务");
                    }));
                    ta.Start();
                    Console.WriteLine("小文:开始整理家务了");
                    for (var i = 0; i <= 10; i++)
                    {
                        Console.WriteLine("小文:已经整理了第{0}项家务了。", i);
                        Thread.Sleep(1000);
                    }
  • 相关阅读:
    CollectionView Header And Footer 的使用
    UICollectionView 的添加自定义高度的区头
    利用SDWebImage 清理缓存
    iOS tableView 中 UITableView中UITableViewStyleGrouped和UITableViewStylePlain的区别
    关于tableview的分割线隐藏问题
    改变输入框的placehould的颜色 和边框颜色
    将代码在有xib得情况下设置到最底层(即执行顺序不是先执行xib) 将图片毛玻璃状态
    通知监听键盘高度变化 自适应键盘高度
    iOS 定义枚举
    iOS 快速存储到本地
  • 原文地址:https://www.cnblogs.com/suanshun/p/6069307.html
Copyright © 2011-2022 走看看