C#Singleton日志类,在销毁时存储磁盘上的消息

时间:2013-07-18 14:55:18

标签: c# asp.net session singleton

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

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

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

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

b]析构函数何时调用会话作用域对象?是仅在会话在服务器上过期时?

2 个答案:

答案 0 :(得分:1)

要完成此实现IDisposable,然后将记录器的实例包装在using块中,这样可以保证在记录器上调用dispose方法。

答案 1 :(得分:1)

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

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

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

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

b)不知道,但无关紧要,因为无论如何你都不能使用终结器。

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

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

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