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



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

同样在同一应用程序中,我有一个GlobalExceptionHandler类来处理所有预期和意外的异常。异常的处理完全是关于记录文件。因此,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方法,该方法将由同一线程执行。HandleException将再次致电Log.由于线程已经有锁,它可以重新输入,然后重新尝试写入文件。这种情况将继续下去。

我的理解正确吗?还是会在我们到达globalExceptionHandler.HandleException(ex)行后立即释放锁定(因为我们已经到达了关键部分的末尾并且HandleException方法没有明确锁定logWriteLock)?

我有一种直觉,我有循环引用,就会发生僵局。

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

还是会在我们上线后立即释放锁 globalExceptionHandler.HandleException(ex) (因为我们已经到了最后 的关键部分和方法句柄异常没有明确 锁定日志写锁)?

您仍然在锁定部分内,从锁定部分调用方法时进入的深度级别无关紧要。

所以你会在握着锁的同时永远在里面循环。

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

相关内容

最新更新