【发布时间】:2019-10-28 03:35:33
【问题描述】:
我们如何解决由终结器引发的未处理异常,它显然不是来自我们的代码?
通过事件AppDomain.CurrentDomain.UnhandledException,我们偶尔会记录一个异常,该异常不是来自我们的代码并且正在终止程序。 stacktrace 以Finalize() 方法开始,并在A 类上调用,我们不会在任何地方使用它。
问题
- 我们能否以某种方式检测导致此问题的库/NuGet/项目?
- 我们可以做一些硬核技巧,比如:
- 更改 GC 行为(在终结器上捕获异常、打印错误对象...)
- 不断在内存中查找所有
A实例并识别其来源(是什么创建了它们或对它们有引用),或者在适当的时候在 try catch 中调用它们的终结器?
- 还有别的吗?
具体信息:
完整的堆栈跟踪以帧 System.ComponentModel.Component.Finalize() 和 System.IO.FileSystemWatcher.Dispose(Boolean disposing) 开始。 FileSystemWatcher 派生自 Component 类 - 因此在 FileSystemWatcher 上调用终结器。
我们不在代码中的任何地方使用FileSystemWatcher 类。它可能来自一些 NuGet,但我们使用其中的许多。我们的解决方案很广泛,我们不知道它会导致什么。我们使用在 Linux 上的 docker 中运行的 .Net Core 2.2。
记录的异常信息:
AggregateException: One or more errors occurred. (Object reference not set to an instance of an object.);
InnerException: NullReferenceException: Object reference not set to an instance of an object.
Stacktrace:
at System.Threading.CancellationTokenSource.CallbackNode.<>c.<ExecuteCallback>b__10_0(Object s)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
--- End of inner exception stack trace ---
at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
at System.IO.FileSystemWatcher.StopRaisingEvents()
at System.IO.FileSystemWatcher.Dispose(Boolean disposing)
at System.ComponentModel.Component.Finalize()
【问题讨论】:
-
我会对那个 lambda 函数感兴趣。
-
错误是
System.Threading.CancellationTokenSource.ExecuteCallbackHandlers,由 Finalize 在某处调用。该错误也来自您的应用程序,否则将是第二次机会异常。 虽然这一切很容易知道,但这将如何解决您的问题... a) 增强日志记录以便能够重现问题,stackoverflow.com/questions/30326673/…,b) 在 ILSply 中打开解决方案并将其保存为 C# 解决方案,在导致问题的 NuGet 包中查找 FileWatcher。 -
@JeremyThompson 非常感谢您的建议,根据他们的建议,我们将尝试以下两件事:1. b):在整个解决方案上使用 ILSpy 2. 灵感来自 a) 链接:我们将部署在我们的测试环境是最失败的微服务的 Debug 版本,然后使用 VS 远程调试器连接到它,并将其设置为仅在 NullReferenceExceptions 上中断。当它中断时,我们将调查回调(lambda 函数)对象。明天我们应该有答案了。
-
这只是一个dumb bug,更新到最新的.netcore 版本来修复。关于这一点可以说很多,但请注意 Docker 对您没有多大帮助。可能让你锁定了错误的版本。在敏捷时代,不断更新是很重要的。一般来说,.NETCore 版本 major.x.y 对于低 y 值是有风险的,它还没有暴露在足够的现实生活中。
-
我们的下一个尝试将是:升级到 .Net Core 3,作为没有 AspNetCore 库的控制台应用程序运行,检查旧版本的应用程序以了解此异常何时开始,在 Windows 而不是 Linux 上运行, ... 但是我们将在一个月内完成这些步骤,因为现在我们必须开发其他东西。如果您有任何新的建议,请在此处提出。
标签: c# .net-core unhandled-exception finalizer