.NET线程监控

4

我希望能够从一个线程中监视另一个线程。目前正在查看线程的isalive属性。如果线程中有任何异常,仍然会返回true。

如果线程中有任何异常或者线程处于无限循环状态,我想要终止该线程。

非常感谢您提供的意见/解决方案/建议。

Raju

2个回答

3
听起来被监控的线程正在捕获它抛出的异常,否则,它将终止并可能导致整个进程崩溃。 您可以订阅 AppDomain.FirstChanceException 事件以了解何时初始引发异常,但即使发生这种情况,您也不一定想要终止线程(如果线程捕获异常,处理它并正常进行呢?)。 相反,考虑让异常“正常”地终止线程,然后在监视器代码中捕获它以防止其导致进程崩溃。

无法判断线程是否处于无限循环状态,但是可以杀死运行时间过长的线程(请参见下面的示例代码)。 然而,使用 Thread.Abort 强制终止线程可能会导致问题并且是不良设计的表现(请参见 此处)。 您应该考虑更改工作线程以管理其自身生存期。

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
通常这是过度设计的迹象。绝大多数程序根本不需要这个。
如果你确实需要检测线程中的无限循环,那么你应该将线程逻辑结构化为一个主循环,并让它“checkin”到一个看门狗。主循环当然是无限的(除非线程被期望“完成”),但这将捕获嵌套在主循环中的任何无限循环。
问题是:这个“看门狗”是什么?
它不能是同一AppDomain中的另一个线程。在这种情况下Thread.Abort线程是完全不合适的。
它可能是一个单独的AppDomain中的线程。就我个人而言,我并不完全满意在AppDomain回收期间发生的“尽力而为但不能保证”的清理,所以我完全避免使用多个AppDomains。
它可以是一个进程。这种解决方案在非常重要的自动化解决方案中相当普遍。
它也可以是另一台计算机。这种解决方案用于关键的自动化解决方案。我曾经做过的大部分工作都涉及到每台计算机上的看门狗进程,以及提供热备份故障转移集群的看门狗计算机。
但我可以诚实地说,98%的情况下,这个问题的答案是“确保你不要在线程中放置无限循环。”换句话说,设计和代码审查结合良好的测试策略通常是最好的解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接