25.4.2 使用WaitHandle

除了使用EndInvoke等待异步方法调用完毕,还可以使用WaitHandle类型的WaitOne方法。WaitOne方法有5个重载:

❑bool WaitOne()

❑bool WaitOne(int millisecondsTimeout)

❑bool WaitOne(TimeSpan timeout)

❑bool WaitOne(int millisecondsTimeout,bool exitContext)

❑bool WaitOne(TimeSpan timeout,bool exitContext)

其中,第1个不带任何参数的重载实际是对WaitOne(-1,false)方法的调用。方法的第1个参数表示等待的毫秒数,值为-1表示无限期等待。第2个参数表示在等待前是否退出上下文的同步域,并在稍后进行重新获取,是则为true,否则为false。

第4个和第5个重载实际上相同的,其中第5个重载会将TimeSpan类型转换为毫秒数,事实上就是转为了对重载4的调用。

同理,第2个重载实际是对重载4的调用,只不过参数2的值为false,而第3个重载实际是对重载5的调用,第2个参数值也为false。

可见,这些重载的核心实现为第4个重载,其他的重载都是对于参数类型或个数的改变。实际上,这些重载都是对WaitHandle对象的一个私有方法bool WaitOne(long timeout,bool exitContext)的调用。

我们在代码清单25-5中使用的也是第4个重载。

代码清单25-5 使用WaitHandle


using System;

using System.Threading;

namespace ProgrammingCSharp4

{

class AsynchronousSample

{

public delegate void PrintDelegate(string content);

public static void Main()

{

//当前线程ID

int threadId=Thread.CurrentThread.ManagedThreadId;

PrintDelegate printDelegate=AsynchronousSample.Print;

Console.WriteLine(“[主线程id:{0}]\t开始调用打印方法……”,threadId);

IAsyncResult result=printDelegate.BeginInvoke("Hello World!",null,null);

result.AsyncWaitHandle.WaitOne(5000,false);

}

public static void Print(string content)

{

int threadId=Thread.CurrentThread.ManagedThreadId;

Console.WriteLine(“[当前线程id:{0}]\t{1}”,threadId,content);

System.Threading.Thread.Sleep(2000);

Console.WriteLine(“[当前线程id:{0}]\t打印方法调用完毕.”,threadId);

}

}

}


上述代码的输出结果为:


[主线程id:1]开始调用打印方法……

[当前线程id:3]Hello World!

[当前线程id:3]打印方法调用完毕.


图25-5演示了使用WaitHandle这一过程。

25.4.2 使用WaitHandle - 图1

图 25-5 使用WaitHandle