gpt4 book ai didi

c# - 多线程丛林中的全局异常处理 - 故障安全/重启

转载 作者:行者123 更新时间:2023-11-30 22:32:17 28 4
gpt4 key购买 nike

情况:
我有一个非常复杂的控制台应用程序,启动多个线程,每个线程生成子线程等等(3 或 4 个级别)。一切都主要是委托(delegate)/事件驱动的。我知道线程创建范围内的 try/catch block 在线程开始执行时与该线程无关。我想找到一种干净的方法来管理它。

出于说明目的,以下模式经常出现在我的应用程序的多个级别:

    public void Activate()
{
ThreadPool.QueueUserWorkItem(Activate_Entrypoint);
}

问题:
只要我还在开发/调试,异常就会在微观层面“随流”抛出。
但是,我现在需要构建和准备一个生产包,所以万一出现异常,一切都需要顺利运行。所以我需要一个干净的用户消息/日志并在顶层关闭/重启。

异常引发模式:
我已经实现了 OnUnhandledException

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);

然而,它似乎并没有像我预期的那样被提升。勘误编辑:它确实正确地提升了,它没有触发,因为我也声明了绑定(bind)主要后期。
我在启用/禁用的不同线程中嵌套了一个除以零来监视应用程序的行为。

重要 - 简洁的设计:
我需要 Main Top Thread 只是一个简而言之,在应用程序的其余部分有一个观察者。如果发生严重错误,我希望该线程停止一切(中止它已启动的子 App 线程),然后重新启动它。你听到了:我不希望丑陋的崩溃只是停止一切。我想将应用程序隔离在一个包装器线程中,该线程将负责检查它是否仍在运行并重新启动它(这是一个 24/7 服务器端应用程序)。我还想避免在任何地方处理所有可能的异常,这将是 hell 。我只想要一条安全带,让未处理的异常在碰巧发生时爆炸,并通过从主线程重新启动应用程序以干净的方式管理它们。

可能的解决方案:
我看到了一些关于标志传递和线程间定期检查的帖子。这听起来很有趣,尽管在使用大量线程级别时它会变得复杂。我正在使用 Quartz.net 在某些标志上安排持续扫描任务,并采取措施使线程停止并在需要时重新启动。尚未完成,只是试一试。

如果我遗漏了什么,请多多包涵并询问详情,这不是我真正熟悉的领域(目前还不是)。

资源: Joseph Albahari on Threading/

最佳答案

您面临的问题记录在 this MSDN documentation 中:

Unhandled exceptions on thread pool threads terminate the process. There are three exceptions to this rule:

A ThreadAbortException is thrown in a thread pool thread, because Abort was called.

An AppDomainUnloadedException is thrown in a thread pool thread, because the application domain is being unloaded.

The common language runtime or a host process terminates the thread.

If any of these exceptions are unhandled in threads created by the common language runtime, the exception terminates the thread, but the common language runtime does not allow the exception to proceed further.

If these exceptions are unhandled in the main thread, or in threads that entered the runtime from unmanaged code, they proceed normally, resulting in termination of the application.

根据此信息,您将必须处理每个父线程中的异常。

我们处理非常相似的设计的方式是跟踪在父集合中启动的每个线程。

在每次通过父进程的主循环时,我们都会检查每个线程的状态。当线程不再处于事件状态(或在一段时间内没有响应)时,我们知道发生了一些问题,因此我们对子进程执行正常关闭,然后,对于除顶级进程之外的所有进程,我们终止线程。

然后,当主线程执行下一次遍历时,它会看到子线程已经死亡,并在必要时重新启动它们。

我们已经使用相同的基本设计运行了至少 10 年(我们在 VB6 中启动了核心)并且它在许多不同的配置和负载中表现非常出色。

关于c# - 多线程丛林中的全局异常处理 - 故障安全/重启,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8794924/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com