【问题标题】:C# Singleton Log Class that Stores Messages on Disk On DestructionC# Singleton 日志类,在销毁时将消息存储在磁盘上
【发布时间】:2013-07-19 20:27:59
【问题描述】:

我有一个 ASP.NET C# 单例(通过 HttpContext.Current.Session 限定为会话),它接收来自代码的消息(警告、错误、异常等)。这些消息与代码问题有关,主要在调试时使用,而不是在生产过程中。

我为此对象编写了自定义析构函数,以便将其内容作为文件写入/附加到磁盘上。

我想问与这种情况有关的两件事:

a] 在对象析构期间打开文件并写入文件是个好主意吗?并发IO访问是通过静态锁来处理的。

b] 什么时候为会话范围的对象调用析构函数?只有当会话在服务器上过期时?

【问题讨论】:

  • 这听起来像是一个奇怪的定制解决方案。调查 ELMAH(很少的配置)............和 ​​log4Net(一些基本的代码更改......但是“发布”代码已经创建......将您的消息发布到.. Sql Server到文本文件到许多其他选项............已经完成了。
  • 析构函数实际上是override void Finalize() 方法。您无法控制何时调用它,GC 会在托管堆栈已满并且它位于其链表中的下一个时执行。
  • 听起来您将所有消息都存储在内存中 (List<string>?),并且在会话结束时将它们写出来。为什么不立即登录?
  • @Corak 是的,谢谢,我也认为这是重构过程的一部分,我可能会这样做。当您在没有明确规范的情况下进行开发时,您可能知道它通常是怎样的。您不断添加功能,因为需求发生变化,然后在某些时候,您需要停止并重构整个类。以前我们不需要此对象写入磁盘日志。

标签: c# asp.net session singleton


【解决方案1】:

我还建议使用一些现有的日志记录包。如果您决定自己做这件事,并且只是为了将来考虑:

a) 不,这不是一个好主意。您不应该在终结器(析构函数)中访问托管资源,因此,例如,如果您在内存中有一些日志字符串,那么访问它们(或它们包含的列表)是不好的做法,因为它们可能已经在这一点。

我不想重复推荐的模式,请参阅https://stackoverflow.com/a/1943856/2586804

您会看到在Dispose 期间只有一个您应该访问的地方被管理,这就是如果它被用户代码调用而不是 GC。因此,这应该可以帮助您得出结论,要实现此目的,您必须自己调用.Dispose()(或使用using),因为当(如果)GC 执行此操作时,它无法访问包含日志行。

b) 不知道,但没关系,因为无论如何您都不能为此目的使用终结器。

底线是您不能依赖 GC 为您运行代码。这是不好的做法,因为您不知道什么时候会发生,再加上现在或将来在任何地方对对象的任何引用都会阻止对象被收集并引入错误。

您也不应该让 c# Finalizers/Destructors 来运行代码,因为这不是它们的用途,它们是用于释放非托管资源以使机器不会耗尽。请注意,在 C# 中很少使用它们,因为大多数人的日常工作都是使用托管对象。

而不是明确地告诉对象写入它的日志,一个名为Flush 的方法将是一个好名字。或者只是让它一次写一行。这将是通常的行为。

【讨论】:

  • 感谢您的回答。我不会使用现有的日志记录包,主要是因为我想了解事情是如何工作的(例如在这种情况下)。话虽如此,当我在类析构函数中时,我用于存储的 List 可能已经被收集了?这违背了我虽然 GC 所做的 - 收集未引用的对象。关于问题(b)的任何提示?也谢谢你的链接,我会尽快阅读。
  • 我建议你阅读这个答案stackoverflow.com/a/538238/2586804:特别注意:“完全有可能在你的 Dispose() 代码中,你试图摆脱的托管对象(因为你想提供帮助)不再存在”和“所以你需要一种方法让 Finalize() 告诉 Dispose() 它不应该接触任何托管资源(因为它们可能不再存在了)"
  • 也适用于 b) 这无关紧要,即何时调用终结器并不重要,因为无论如何您都无法将终结器用于您的目的。
  • 谢谢。这可能与本案无关,但总的来说我只是好奇。
【解决方案2】:

要实现此功能,请实现 IDisposable,然后将记录器的实例包装在 using 块中,这将保证调用记录器上的 dispose 方法。

【讨论】:

  • 这适用于 ASP.NET 会话范围的单例吗?我不希望实例在整个会话期间超出范围。但也许我只是误解了建议的解决方案,即究竟要在 using 块中包装什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2013-04-13
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多