You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关闭被多对象引用的C# Logger类中的StreamWriter?

解决Logger类中StreamWriter的资源释放问题

针对你遇到的StreamWriter关闭时机问题,最规范的做法是让Logger类实现IDisposable接口,通过Dispose模式管理资源,既能让用户在合适时机手动释放,也能通过using语句自动处理。

修改后的Logger类代码

internal class Logger : IDisposable
{
    private readonly string logFilePath;
    private StreamWriter? writer;
    private bool disposed = false;

    public Logger(string name)
    {
        string date = DateTime.Now.ToString("yyyy-MM-dd");
        logFilePath = string.Format(".\\logs\\{0}_log_{1}.log", name, date);

        // 简化逻辑:StreamWriter的append参数设为true,自动处理文件存在/不存在的情况
        writer = new StreamWriter(logFilePath, true);
    }

    internal void Log(string message)
    {
        if (disposed)
            throw new ObjectDisposedException(nameof(Logger));

        string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        writer.WriteLine("{0} - {1}", time, message);
        // 可选:立即刷新缓冲区,避免程序崩溃时丢失未写入的日志
        writer.Flush();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // 释放托管资源:关闭并销毁StreamWriter
                writer?.Close();
                writer?.Dispose();
            }

            writer = null;
            disposed = true;
        }
    }

    // 析构函数:作为最后保障,即使忘记调用Dispose,GC回收时也会尝试释放资源
    ~Logger()
    {
        Dispose(false);
    }
}

使用方式

  1. 推荐:用using语句自动释放
    当Logger对象的使用范围明确时,用using包裹,超出范围后会自动调用Dispose关闭StreamWriter:
using (var logger = new Logger("MyApp"))
{
    logger.Log("程序启动完成");
    // 执行其他日志操作
}
// 此处logger已自动释放资源
  1. 手动调用Dispose
    如果Logger是全局对象或使用范围不明确,在确定不再使用时手动调用Dispose:
var logger = new Logger("MyApp");
logger.Log("执行了某个操作");
// 不再需要日志功能时
logger.Dispose();

额外优化说明

  • 简化了文件打开逻辑:StreamWriter的append参数设为true后,不管文件是否存在都会自动追加内容,无需提前判断File.Exists。
  • 添加了资源释放校验:避免在Logger已释放后调用Log方法引发异常。
  • 可选的Flush调用:默认StreamWriter会缓冲写入内容,调用Flush能确保日志立即写入文件,降低程序意外退出时的日志丢失风险。

内容的提问来源于stack exchange,提问作者BeeFriedman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:27:41