C#同步和异步(四)等待异步调用完成

如果有一种特殊需求,我们希望等待异步调用结束后继续执行后面的语句。这种形式和同步一样。那么怎么实现呢?

下面介绍两种实现方式:

1、简单方式

利用IAsyncResult中的IsCompleted属性。此属性指示异步调用是否成功完成。 BeginInvoke()方法返回值为IAsyncResult类型数据。有关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; }
    }

第1种实现方式如下:

#region  //异步等待调用方式1(现象与同步类似)
private void button4_Click(object sender, EventArgs e)
{
    //输出开始时间,当前线程名
    Console.WriteLine("异步等待1调用开始,当前线程为:" + Thread.CurrentThread.ManagedThreadId.ToString("00") + '\n');

    Action action1 = this.doSomething1;         //将方法1赋值给action1

    IAsyncResult asyncResult1;

    for (int i = 0; i < 5; i++)
    {
        asyncResult1 = action1.BeginInvoke("异步等待1", null, "C#自学");  //方法1开始异步调用,无回调参数

        while (!asyncResult1.IsCompleted)               //等待当前的线程调用完毕后跳出
        {
            Thread.Sleep(200);                          //作200ms的延时
        }
    }
           
    //输出结束时间,当前线程名
    Console.WriteLine("异步等待1调用结束,当前线程为:" + Thread.CurrentThread.ManagedThreadId.ToString("00") + '\n');
}
#endregion

 

2、利用AsyncWaitHandle.WaitOne()来设置等待

#region  //异步等待调用方式2
private void button5_Click(object sender, EventArgs e)
{
    //输出开始时间,当前线程名
    Console.WriteLine("异步等待2调用开始,当前线程为:" + Thread.CurrentThread.ManagedThreadId.ToString("00") + '\n');

    Action action1 = this.doSomething1;         //将方法1赋值给action1

    IAsyncResult asyncResult1;

    for (int i = 0; i < 5; i++)
    {
        asyncResult1 = action1.BeginInvoke("异步等待2", null, null);  //方法1开始异步调用,无回调参数

        asyncResult1.AsyncWaitHandle.WaitOne();  //等待任务完成
        //asyncResult1.AsyncWaitHandle.WaitOne(-1);  //等待任务完成
        //asyncResult1.AsyncWaitHandle.WaitOne(1000);  //最多等待1000ms,超时就不等待了
    }

    //输出结束时间,当前线程名
    Console.WriteLine("异步等待2调用结束,当前线程为:" + Thread.CurrentThread.ManagedThreadId.ToString("00") + '\n');
}
#endregion

上面两种方法类似输出的结果如下:

C#同步和异步(四)等待异步调用完成_第1张图片

上述结果我们可以看出,利用异步调用等待,可以控制异步调用结束后才执行下一步骤。这种情况与同步效果类似,但区别是异步调用的所用的线程仍然是新开辟的线程。

你可能感兴趣的:(C#宝典)