2010-08-23 75 views
3

我想监视另一个线程的一个线程。当前正在查看threasd.isalive属性。如果线程仍然有任何异常,则线程.isiveive属性为true。.net线程监视

我想如果在线程,或者如果线程处于无限循环的任何异常杀死线程..

会appreacite您输入/解决方案/建议。

拉朱

回答

2

这听起来像监视线程捕捉它抛出异常,否则将终止,可能把你的整个过程下来为好。您可以订阅AppDomain.FirstChanceException事件以确定何时最初引发异常,但即使发生这种情况,您也不一定要终止线程(如果线程捕获异常并进行处理并正常执行,该怎么办?) 。相反,考虑让异常终止线程“正常”,然后将其捕获到监视器代码中,以防止它终止进程。

无法确定线程是否处于无限循环中,但是您可以终止运行时间过长的线程(请参阅下面的示例代码)。然而,用Thread.Abort强制终止线程可能会导致问题,并且是代码异味(请参阅here)。您应该考虑更改工作线程以管理其自己的生命周期。

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (RunWithTimeout(LongRunningOperation, TimeSpan.FromMilliseconds(3000))) 
     { 
      Console.WriteLine("Worker thread finished."); 
     } 
     else 
     { 
      Console.WriteLine("Worker thread was aborted."); 
     } 
    } 

    static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout) 
    { 
     Thread workerThread = new Thread(threadStart); 

     workerThread.Start(); 

     bool finished = workerThread.Join(timeout); 
     if (!finished) 
      workerThread.Abort(); 

     return finished; 
    } 

    static void LongRunningOperation() 
    { 
     Thread.Sleep(5000); 
    } 
} 
3

通常这是过度设计的标志。绝大多数程序根本不需要这个。

如果你真的需要检测线程无限循环,那么你应该构建线程的逻辑是在一个主循环,并让它“签入”到看门狗。主循环当然是无限的(除非线程被期望“完成”),但是它会捕获嵌套在主循环中的任何无限循环。

问题是:这个“看门狗”是什么?

它不能是同一AppDomain中的另一个线程。在这种情况下,Thread.Abort线程完全不合适。

它可能是一个单独的AppDomain中的线程。就个人而言,我并不完全满意AppDomain回收过程中发生的“尽力但不保证”的清理,所以我完全避免了多个AppDomain。

它可能是一个过程。该解决方案在非常重要的自动化解决方案中非常常见

它也可能是另一台电脑。该解决方案用于关键的自动化解决方案。我曾经做过的大部分工作都涉及每台计算机上的监视程序进程以及提供一种热备份故障转移群集的监视计算机。

不过,我可以诚实地说,98%的问题被问到,答案是“只要确保你不要在线程中放入一个无限循环。”换句话说,设计和实施看门狗解决方案的巨大成本根本不在实际需求的范围内。设计和代码评审以及良好的测试策略通常是最佳解决方案。