c# - 锁定未处理的异常处理程序是否安全?

标签 c# multithreading exception deadlock

鉴于:

  • 在终结器中获取锁可能会导致死锁
  • 终结器可以抛出异常

在未处理的异常处理程序中获取锁是否安全,或者下面的代码会导致死锁吗?

static void Main(string[] args)
{
     AppDomain.CurrentDomain.UnhandledException += 
         new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
     //do other stuff
}

private static object loggingLock = new object();

static void CurrentDomain_UnhandledException(
    object sender, 
    UnhandledExceptionEventArgs e)
{
    lock (loggingLock)
    {
        //log the exception
    }
}

最佳答案

Given that:

  • taking a lock while in a finalizer can cause deadlocks
  • finalizers can throw exceptions

编辑事实证明,根据定义,终结器中抛出的异常是致命的:

doc: If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active try-finally blocks or finalizers are executed. This behavior ensures process integrity if the finalizer cannot free or destroy resources.

See also c# finalizer throwing exception?

注意:即使异常可能源自函数内部,但这并不意味着它将在该函数的上下文中进行处理。事实上,堆栈将被展开:

doc: An exception is unhandled only if the entire stack for the thread has been unwound without finding an applicable exception handler, so the first place the event can be raised is in the application domain where the thread originated.


我不明白为什么锁定不安全。 (通常的警告适用:在持有锁时不要执行阻塞操作...)。

但是,您可能需要在此处重新考虑可重入性和无限递归:

  • 您将如何应对日志记录时的错误根据定义将获取锁,因为线程已经持有它。但是日志代码是可重入的吗?即:调用另一个 log 操作会扰乱正在进行的(失败/失败)操作的状态吗?日志记录可能吗?

    --> 如果不允许重入(或需要特殊操作(例如在其他地方记录),即使获取了锁,您也需要显式的“inLoggingOperation”标志,因为锁不会阻止单线程重入

  • 小要点:如果您的日志记录不完全防异常,那么当您已经处于 CurrentDomain.UnhandledException 中时,您可能会遇到麻烦(AFAICT the docs do not describe 在事件处理程序中引发异常时会发生什么)。

关于c# - 锁定未处理的异常处理程序是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12630042/

相关文章:

java - 如何摆脱这个 java.io.EOFException?

c# - 如何在客户端使用接口(interface)注入(inject)WCF服务?

java - Thread 的 run() 方法中的最终枚举

java - java多线程客户端-服务器架构中从run()方法调用方法

exception - 为什么从 ASP.NET 页面调用的 DLL 中出现异常后,我的 IIS7 应用程序池会关闭?

asp.net - WinForms 和 Asp 类库中的异常处理

c# - 将 Python 中的 SHA 哈希计算转换为 C#

c# - 如何使用 Monotouch 遍历 CGPDFDictionary?

c# - 为什么此处需要引用未使用的程序集

c - 新手线程问题 (FFTW)