gpt4 book ai didi

c# - 类析构问题

转载 作者:太空狗 更新时间:2023-10-29 19:52:12 26 4
gpt4 key购买 nike

我正在制作一个包含 StreamWrite 的简单类

    class Logger
{
private StreamWriter sw;
private DateTime LastTime;
public Logger(string filename)
{
LastTime = DateTime.Now;
sw = new StreamWriter(filename);
}
public void Write(string s)
{
sw.WriteLine((DateTime.Now-LastTime).Ticks/10000+":"+ s);
LastTime = DateTime.Now;
}
public void Flush()
{
sw.Flush();
}
~Logger()
{
sw.Close();//Raises Exception!
}
}

但是当我在析构函数中关闭这个 StreamWriter 时,它引发了一个异常,表明 StreamWriter 已经被删除了?

为什么?以及如何使其工作,以便在删除 Logger 类时,在删除之前关闭 StreamWriter?

谢谢!

最佳答案

在 99.99% 的情况下,编写自己的析构函数(又名终结器)是错误的。需要它们来确保您的类释放未由 .NET 框架自动管理且未由您的类的用户正确释放的操作系统资源。

首先必须在您自己的代码中分配操作系统资源。这总是需要某种 P/Invoke。这是非常很少需要的,这是在 Microsoft 工作的 .NET 程序员的工作。

他们在 StreamWriter 的案例中做到了。通过几个层,它是一个文件句柄的包装器,由 CreateFile() 创建。创建句柄的类也是负责编写终结器的类。 Microsoft 代码,不是你的。

这样的类总是实现 IDisposable,让类的用户有机会在用完资源后释放资源,而不是等待终结器完成工作。 StreamWriter 实现 IDisposable。

当然,您的 StreamWriter 对象是您的类的私有(private)实现细节。您不知道用户何时完成您的 Logger 类,您不能自动调用 StreamWriter.Dispose()。你需要帮助。

通过自己实现 IDisposable 获得帮助。您的类的用户现在可以调用 Dispose 或使用 using 语句,就像她使用任何框架类一样:

  class Logger : IDisposable {
private StreamWriter sw;
public void Dispose() {
sw.Dispose(); // Or sw.Close(), same thing
}
// etc...
}

好吧,在 99.9% 的情况下你都应该这样做。但不是在这里。冒着让您产生致命困惑的风险:如果您实现了 IDisposable,则您的类的用户还必须有合理的机会调用其 Dispose() 方法。这通常不是什么大问题,除了 Logger 类型类。您的用户很可能希望在最后一刻记录某些内容。例如,这样她就可以记录来自 AppDomain.UnhandledException 的未处理异常。

在这种情况下何时调用 Dispose()?您可以在程序终止时执行此操作。但这不是重点,如果它发生在程序退出时,那么提前释放资源没有多大意义。

记录器有在所有情况下正确关闭的特殊要求。这需要您将 StreamWriter.AutoFlush 属性设置为 true,以便日志输出在写入后立即刷新。考虑到正确调用 Dispose() 的难度,现在实际上最好不要实现 IDisposable 并让 Microsoft 的终结器关闭文件句柄。

Fwiw,框架中还有一个类有同样的问题。 Thread 类使用四个操作系统句柄但不实现 IDisposable。调用 Thread.Dispose() 真的很笨拙,所以 Microsoft 没有实现它。这在非常不寻常的情况下会导致问题,您需要编写一个程序来创建大量线程,但从不使用 new 运算符来创建类对象。已经完成了。

最后但同样重要的是:如上所述,编写记录器相当棘手。 Log4net 是一种流行的解决方案。 NLog 是一个更好的捕鼠器,它是一个感觉和工作都是点网的库,而不是感觉像一个 Java 端口。

关于c# - 类析构问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2529222/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com