使用上面通过IAsyncResult设计模式实现的带ref引用参数的异步操作,我将展示三种阻塞式响应异步调用和一种无阻塞式委托响应异步调用。即:

  1、执行异步调用后,若我们需要控制后续执行代码在异步操作执行完之后执行,可通过下面三种方式阻止其他工作:

  a)IAsyncResult的AsyncWaitHandle属性,待异步操作完成时获得信号。

  b)通过IAsyncResult的IsCompleted属性进行轮询。通过轮询还可实现进度条功能。

  c)调用异步操作的 End*** 方法。

  2、执行异步调用后,若我们不需要阻止后续代码的执行,那么我们可以把异步执行操作后的响应放到回调中进行。
public class Calculate_Test 

    public static void Test() 
    { 
        CalculateLib cal = new CalculateLib(); 
  
        // 基于IAsyncResult构造一个异步API 
        IAsyncResult calculateResult = cal.BeginCalculate(123, 456, AfterCallback, cal); 
        // 执行异步调用后,若我们需要控制后续执行代码在异步操作执行完之后执行,可通过下面三种方式阻止其他工作: 
        // 1、IAsyncResult 的 AsyncWaitHandle 属性,带异步操作完成时获得信号。 
        // 2、通过 IAsyncResult 的 IsCompleted 属性进行轮询。通过轮询还可实现进度条功能。 
        // 3、调用异步操作的 End*** 方法。 
        // *********************************************************** 
        // 1、calculateResult.AsyncWaitHandle.WaitOne(); 
        // 2、while (calculateResult.IsCompleted) { Thread.Sleep(1000); } 
        // 3、 
        string resultStr = string.Empty; 
        int result = cal.EndCalculate(ref resultStr, calculateResult); 
    } 
  
    /// <summary> 
    /// 异步操作完成后做出响应 
    /// </summary> 
    private static void AfterCallback(ref string resultStr, IAsyncResult ar) 
    { 
        // 执行异步调用后,若我们不需要阻止后续代码的执行,那么我们可以把异步执行操作后的响应放到回调中进行。 
        CalculateLib cal = ar.AsyncState as CalculateLib; 
  
        //int result = cal.EndInvoke(ref resultStr, calculateResult1); 
        //if (result > 0) { } 
    } 
}

  二、使用委托进行异步编程

  对于委托,编译器会为我们生成同步调用方法“invoke”以及异步调用方法“BeginInvoke”和“EndInvoke”。对于异步调用方式,公共语言运行库 (CLR) 将对请求进行排队并立即返回到调用方,由线程池的线程调度目标方法并与提交请求的原始线程并行运行。

  异步委托是快速为方法构建异步调用的方式,它基于IAsyncResult设计模式实现的异步调用,即,通过BeginInvoke返回IAsyncResult对象;通过EndInvoke获取结果值。

  示例:

  上节的CalculateLib类中的同步方法以及所要实用到的委托如下:
// 带ref参数的自定义委托 
public delegate int AsyncInvokeDel(int num1, int num2, ref string resultStr); 
public int Calculate(int num1, int num2, ref string resultStr) 

    resultStr = (num1 * num2).ToString(); 
    return num1 * num2; 
}