在类库级别捕捉c#错误

本文关键字:错误 类库 | 更新日期: 2023-09-27 17:54:53

我正在尝试为企业级类库制定错误日志记录解决方案。部分要求:

  • 它将被多个端点应用程序使用(因此为什么它应该在类库中处理)
  • 它应该将其数据沉入SQL Server数据库以便于存储。这也是第三个:
  • 它应该能够支持自定义web应用程序读取其数据。

还有一个要求,那就是"非常好"。也就是说,它并不重要,但如果它不可行,我最好有一个非常好的理由。

    它不应该在其端点应用程序中要求专门的Logger对象。他们应该能够简单地抛出异常,日志软件应该从那里处理事情。使用特定的USING命令是可以的。

全面考虑一下,前三点并不难。一个快速日志类和一些存储过程,到此为止,对吗?最后一点是我不知道如何处理的。我以前在一个朋友的代码中看到过这样的情况,所以我知道这是可能的,但不幸的是,他的朋友已经去世了,他的代码丢失了。有没有人在那里谁可以指出我在正确的方向有一个类库对象以某种方式捕获所有错误从端点应用程序来处理它们?

在类库级别捕捉c#错误

如果您想捕获所有未处理的异常,而不是源自您自己的调用堆栈,您可以考虑利用AppDomain对象:

AppDomain.CurrentDomain.UnhandledException += (s, e) => {
    // Your logging logic
};
AppDomain.CurrentDomain.FirstChanceException += (s, e) => {
    // Your logging logic
};

听起来微软企业库在这里可以使用…

http://msdn.microsoft.com/en-us/library/ff649552.aspx

当我阅读企业级类库时,我的脑海中有这些需求:

  • 你的组件不能抛出异常并干扰系统。
  • 它应该优雅地处理错误,并能够从错误中恢复。

这些需求对于作为开发人员的您来说是很好的睡前读物。所有的错误场景,甚至是你最疯狂的梦想,迟早会成为现实,你会在凌晨3点尖叫着醒来。

这些要求听起来不错,但其影响深远。如果您试图捕获组件中的所有错误,那么您只需要隐藏错误。这样的系统往往很慢,有时它们会停止工作,没有人知道为什么,因为一些后续错误确实使系统进入了一个什么都不工作的状态。令人遗憾的是,如果您将调试器附加到陈旧的机器上,您将看不到导致问题的原始错误,而是看到一个后续问题,您必须从该问题返回到原始问题。如果您想要记录SQL server,我可以向您保证,您将经常没有或丢失日志。

你应该考虑更可靠的日志目的地(自定义事件日志,日志文件,…或者两者都有)。并且不惜一切代价避免异步日志,因为一个未处理的异常会使进程崩溃,比你在日志线程中记录它的速度要快得多。

实际上,当发生致命错误时,您需要尽可能早地使系统停止。您可以在不破坏状态的情况下安全地恢复的错误通常很少,但它们是值得的,因为您需要将您的类库设计得健壮(处理预期的错误)和安全(抛出异常,记录它们,…)。

在设计阶段,更容易想到一个完美的系统,可以应付所有的错误。软件架构师喜欢这样的系统。他们可以侥幸逃脱,因为在纸面上看起来很好。或者换句话说:泡沫不会破裂。

但是在执行时你的类库正在使用

  • 实际物理内存(OutOfMemoryException)
  • 实际硬盘空间(至少日志文件)(硬盘满)
  • 实际CPU周期(100% CPU)
  • 实际栈空间(StackOverFlowException)

如果你试图隐藏致命错误,系统只会变得更难调试,但它仍然会失败,因为你的库将消耗共享资源,而这些资源并不只属于你的组件。在这种情况下,最好立即停止工作,而不是继续工作,让别人也失败。

将所有错误隐藏在组件中的想法是有缺陷的,因为你无法防止组件中的致命错误影响系统中的其他组件。

话是这么说的,我希望你没有问如何在类库级别捕获所有错误,而是在你的终端应用程序中,你向用户显示错误并记录它们(希望只有一次,而不是在每一层再次,因为你不信任其他层)。正如其他人指出的那样,您可以处理未处理的异常,这些异常确实终止了线程,而当错误处理程序离开时,这些异常反过来又会终止您的进程。除此之外,在Main方法周围放置一个try/catch块以捕获主线程中的错误是一个好主意。如果你的应用程序有一个UI (Windows窗体),你也应该注册到应用程序。当异常从窗口消息处理程序传播出去时,该事件将被调用。

你的,阿洛伊斯•克劳斯