下面是一个具有“SomeMethod”方法的类,它说明了我的问题。
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
// more member declarations
public void SomeMethod()
{
// some code
theEvent.WaitOne();
// more code
}
}
该方法被设计为线程安全的,将在不同的线程中调用。现在我的问题是,如何在任何时候解除对“theEvent”对象调用“WaitOne”方法的所有线程的阻塞?这个要求经常出现在我的设计中,因为我需要能够优雅地停止和启动我的多线程程序。在我看来,启动一个多线程程序相当简单,但要停止一个程序却很棘手。
这是我迄今为止尝试过的显然有效的方法。但这是标准方法吗?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
“UnblockAll”方法是“SomeClass”类的成员。此处使用的技术基于WaitOne 方法的 MSDN 文档。我引用了以下文档的相关部分:
如果毫秒超时为零,则该方法不会阻塞。它测试等待句柄的状态并立即返回。
在 do..while 循环中,我调用Set 方法。这会释放一个可能由于调用 WaitOne 方法而阻塞的线程(编码在“SomeMethod”方法中)。接下来我测试“theEvent”对象的状态,以了解它是否已发出信号。该测试是通过调用带有超时参数的 WaitOne 方法的重载版本来完成的。我在调用 WaitOne 方法时使用的参数为零,根据文档,这会导致调用立即返回一个布尔值。如果返回值为真,则“theEvent”对象为处于信号状态。如果在“SomeMethod”方法中调用“WaitOne”方法时至少有一个线程被阻塞,则对“Set”方法的调用(编码在“UnblockAll”方法中)将解除阻塞。因此,在“UnblockAll”方法中的 do..while 语句末尾调用“WaitOne”方法将返回 false。仅当没有线程阻塞时,返回值才为真。
上述推理是否正确,如果正确,该技术是否是处理我的问题的标准方法?我正在尝试主要在 .net compact-framework 2.0 平台上使用该解决方案。