.net线程监控

时间:2010-08-23 10:10:39

标签: .net

我想监视来自另一个线程的一个线程。目前正在查看threasd.isalive属性。如果线程中仍有异常,则thread.isalive属性为true。

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

会为您的输入/解决方案/建议付出代价。

拉​​朱

2 个答案:

答案 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);
    }
}