以下情况是否存在僵局,有什么解决方案可以防止这种情况发生?

Is there a deadlock in following situation and what could be the solution to prevent it?

我有一个 FileLogger class 将消息记录到 txt 文件中。我的目的是使 FileLogger class 线程安全,以便多个线程可以以线程安全的方式写入日志消息。我有一个锁对象,一次只允许一个线程写入。

同样在同一个应用程序中,我有一个 GlobalExceptionHandler class 来处理所有预期和意外的异常。异常的处理都是关于记录文件的。所以,GlobalExceptionHandler最终会调用FileLoggerLog方法记录到文件中。在代码方面可以表示为:

class FileLogger {

  ...

  public void Log(string logOrigin, string message, LogLevel logLevel) {
    //some code
    lock (logWriteLock) {
        try {
          using (var logFileStream = File.Open(logFilePath, FileMode.Append, FileAccess.Write, FileShare.Read)) {
            logFileStream.Write(messageBytes, 0, messageBytes.Length);
            logFileStream.Flush();
          }
        } catch (Exception ex) { 
          globalExceptionHandler.HandleException(ex);
        }
      }
  }

}

class GlobalExceptionHandler {

  public void HandleException(Exception ex) {
    //some code
    fileLogger.Log(...);
  }
}

我的理解:

线程获得锁logWriteLock,然后尝试打开文件并写入。快乐的场景会很好,但如果在尝试写入时出现异常,那么控件将转到 HandleException 方法,该方法将由相同的 thread.The 执行 HandleException 将再次调用 Log。由于线程已经有了锁,它可以重新进入,然后重新尝试写入文件。这将继续下去。

我的理解对吗?或者一旦我们到达行 globalExceptionHandler.HandleException(ex) 就会释放锁(因为我们已经到达临界区的末尾并且方法 HandleException 没有明确锁定 logWriteLock)?

我有一种直觉,我有循环引用并且会发生死锁。

此外,如果出现死锁,那么可能的解决方案是什么。我们是否需要一个额外的文件来记录 FileLogger 中的异常(我认为这不是一个好主意,因为我们会导致不必要的设计复杂性)?

Or will the lock be released as soon as we hit the line globalExceptionHandler.HandleException(ex) (as we have reached the end of critical section and the method HandleException does not explicitly lock on logWriteLock)?

您仍在锁定部分内,无论您从锁定部分调用方法时进入的深度级别如何。

所以你会一直拿着锁在里面循环。

当日志记录失败时,没有理由尝试记录异常,因为它也可能会失败。因此,要么使用另一种记录器,要么发送通知,以便您可以在出现此类问题时做出反应。