一旦线程加入,我如何发信号通知线程停止等待Mutex?

时间:2010-11-04 18:32:27

标签: .net multithreading join wait

我注意到我的一些服务是挂起而不是按照指示关闭,因为他们正在等待等待他们关闭的其他服务所持有的锁(导致死锁)。为此,我需要某种方式来通知等待锁关闭的线程,所以我想出了这个:

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将超时并且线程将被中止,但我宁愿它不会那样。

所以我有两个问题:

  1. 线程有没有办法知道它已被加入(因此可以停止等待)?

  2. 有没有比我在这里提出的更好的方法来解决这个问题?

2 个答案:

答案 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