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-5 使用WaitHandle