ghd*_*ghd 12 .net c# waithandle waitone compact-framework2.0
下面是一个具有'SomeMethod'方法的类,它说明了我的问题.
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
// more member declarations
public void SomeMethod()
{
// some code
theEvent.WaitOne();
// more code
}
}
Run Code Online (Sandbox Code Playgroud)
该方法设计为线程安全的,并将在不同的线程中调用.现在我的问题是如何在任何时间点取消阻止在'theEvent'对象上调用'WaitOne'方法的所有线程?这个要求经常出现在我的设计中,因为我需要能够优雅地停止和启动我的多线程程序.在我看来,启动一个多线程程序相当简单,但很难阻止它.
这是我迄今为止尝试过的,显然有效.但这是标准方法吗?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
Run Code Online (Sandbox Code Playgroud)
'UnblockAll'方法是'SomeClass'类的成员.此处使用的技术基于WaitOne方法的MSDN文档.我引用下面文档的相关部分:
如果millisecondsTimeout为零,则该方法不会阻止.它测试等待句柄的状态并立即返回.
在do..while循环中,我调用Set方法.这释放了一个可能由于调用WaitOne方法而被阻塞的线程(在'SomeMethod'方法中编码).接下来,我测试'theEvent'对象的状态,只是为了知道它是否有信号.此测试是通过调用带有超时参数的WaitOne方法的重载版本来完成的.我在调用WaitOne方法时使用的参数为零,根据文档结果,调用立即返回一个布尔值.如果返回值是true,那么"theEvent"的对象是信号状态中.如果在'SomeMethod'方法中对'WaitOne'方法的调用至少阻塞了一个线程,则调用'Set'方法(在'UnblockAll'方法中编码)将解除阻塞.因此,在'UnblockAll'方法中do..while语句结束时对'WaitOne'方法的调用将返回false.仅当没有线程被阻止时,返回值才为真.
上述推理是否正确,如果是正确的,该技术是否是处理我的问题的标准方法?我试图主要在.net compact-framework 2.0平台上使用该解决方案.
Bri*_*eon 11
你有三个可行的选择.每个人都有自己的优点和缺点.选择最适合您特定情况的那个.
选项1 - 民意调查WaitHandle.
如果没有给出关闭请求,则使用具有超时的一个并且恢复该块,而不是进行无限期的阻塞调用.
public void SomeMethod()
{
while (!yourEvent.WaitOne(POLLING_INTERVAL))
{
if (IsShutdownRequested())
{
// Add code to end gracefully here.
}
}
// Your event was signaled so now we can proceed.
}
Run Code Online (Sandbox Code Playgroud)
选项2 - 使用单独WaitHandle的请求关闭
public void SomeMethod()
{
WaitHandle[] handles = new WaitHandle[] { yourEvent, shutdownEvent };
if (WaitHandle.WaitAny(handles) == 1)
{
// Add code to end gracefully here.
}
// Your event was signaled so now we can proceed.
}
Run Code Online (Sandbox Code Playgroud)
选项3 - 使用 Thread.Interrupt
不要混淆这个Thread.Abort.中止线程绝对不安全,但中断线程完全不同.Thread.Interrupt将"戳"内建阻塞调用在BCL包括所用Thread.Join,WaitHandle.WaitOne,Thread.Sleep等.