我想监视来自另一个线程的一个线程。目前正在查看threasd.isalive属性。如果线程中仍有异常,则thread.isalive属性为true。
如果线程中有任何异常或线程处于无限循环中,我想杀死线程..
会为您的输入/解决方案/建议付出代价。
拉朱
答案 0 :(得分:3)
通常这是过度设计的标志。绝大多数程序根本不需要这个。
如果确实需要检测线程中的无限循环,那么你应该将线程逻辑构造成一个主循环并让它“签入”看门狗 。主循环当然是无限的(除非线程被期望“完成”),但是这将捕获嵌套在主循环中的任何无限循环。
问题是:这个“看门狗”是什么?
它不能是同一AppDomain中的另一个线程。在这种情况下,Thread.Abort
线程是完全不合适的。
它可能是单独的AppDomain中的一个线程。就个人而言,我对AppDomain回收期间发生的“尽力但不保证”的清理工作并不完全满意,所以我完全避免使用多个AppDomain。
这可能是一个过程。这种解决方案在非常重要的自动化解决方案中相当普遍。
它也可能是另一台计算机。此解决方案用于关键自动化解决方案。我过去做的大部分工作都涉及每台计算机上的监视程序进程,以及提供一种热备份故障转移群集的监视计算机。
但是,我可以诚实地说,98%的时间会问这个问题,答案是“只是确保你首先不要在线程中放置一个无限循环。”换句话说,设计和实施监督解决方案的巨大成本根本不在实际要求的范围内。设计和代码审查与良好的测试策略相结合通常是最佳解决方案。答案 1 :(得分: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);
}
}