我注意到我的一些服务是挂起而不是按照指示关闭,因为他们正在等待等待他们关闭的其他服务所持有的锁(导致死锁)。为此,我需要某种方式来通知等待锁关闭的线程,所以我想出了这个:
public static Boolean Lock(this Mutex mutex)
{
Boolean achieved = false;
while (Thread.CurrentThread.ThreadState != System.Threading.ThreadState.StopRequested)
{
try
{
achieved = mutex.WaitOne(TimeSpan.FromSeconds(10.0));
}
catch (AbandonedMutexException exception)
{
// Log this
}
}
return achieved;
}
当每个服务停止时,它会在每个线程上调用Join。问题是,即使在调用Thread之后,ThreadState仍然设置为Running。最终,Join将超时并且线程将被中止,但我宁愿它不会那样。
所以我有两个问题:
线程有没有办法知道它已被加入(因此可以停止等待)?
有没有比我在这里提出的更好的方法来解决这个问题?
答案 0 :(得分:2)
创建全局手动重置事件,在加入线程之前将其设置为服务关闭,并在WaitHandle.WaitAny (mutex, stopEvent)
函数中使用Lock
:
internal static EventWaitHandle s_stopEvent ;
// in service startup code:
s_stopEvent = new ManualResetEvent (false) ;
public static void Stop (this IEnumerable<Thread> threads)
{
s_stopEvent.Set () ;
foreach (var thread in threads)
thread.Join () ;
}
public static bool Lock (this Mutex mutex)
{
try
{
return WaitHandle.WaitAny (new WaitHandle[] { mutex, s_stopEvent }) == 0 ;
}
catch (AbandonedMutexException exception)
{
// Log this
}
}
答案 1 :(得分:1)
您必须在线程运行的任务中构建取消机制,因此除了取消之外,没有任何线程机制可以提供帮助。
看看这里:
http://www.albahari.com/threading/part3.aspx#_Cancellation_Tokens