***********************请教一个关于IDisposable接口实现的问题***************

时间:2021-01-27 18:26:26
我的代码是这样写的
 public class Log : IDisposable
    {
        private static readonly StreamWriter swWrite = new StreamWriter(System.AppDomain.CurrentDomain.BaseDirectory + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");

        #region 记录日志
        public static void AddLog(string sMessage)
        {
            try
            {
                System.Threading.Monitor.Enter(swWrite);
                swWrite.WriteLine(sMessage + "  " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                swWrite.Flush();
            }
            finally
            {
                System.Threading.Monitor.Exit(swWrite);
            }
        }
        #endregion

        private bool m_bDisposed;

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

        protected virtual void Dispose(bool disposing)
        {
            Log.AddLog("抓取数据结束");
            if (!m_bDisposed)
            {
                if (disposing)
                {
                    swWrite.Close();
                    swWrite.Dispose();
                }
            }
        }

        ~Log()
        {
            Dispose(false);
        }
        

    }

在程序运行完时,我等了一会.后来把进程都结束了.却始终没有执行
Log.AddLog("抓取数据结束");这一句

请问是上面的写法有问题吗

10 个解决方案

#1


我是楼主~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MSDN上说的是Dispose释放托管资源,析构函数释放非托管资源.

推荐这种写法

我这里提供的是静态方法.

而程序里调用这个方法是多线程的.

所以也不可能用using.

#2


up

#3


up

#4


lz 没有理解对象实例和类的区别
dispose 也好 析构函数也好,都是针对某个具体的对象,而不是针对一个类型

#5


Dispose  如果你不是手工调用,就要等.net的回收机制调用才调用

#6


你强制进行GC.Collect

#7


LZ的这一段问题还真不少:
1、Dispose,Finnalize,这些只对实例对象,不是对Class的。LZ就没有实例化过任何对象,所以Log.AddLog("抓取数据结束");这一句一直不会被执行。
2、LZ使用了静态实例对象Stream,没有最终Close。


解决方案:

public class Log
{
    private static readonly StreamWriter swWrite;

    static Log()
    {
        swWrite = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");

        Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
    }

    static void Application_ApplicationExit(object sender, EventArgs e)
    {
        Log.AddLog("抓取数据结束");

        swWrite.Dispose();
        swWrite = null;
    }

    #region   记录日志
    public static void AddLog(string sMessage)
    {
        try
        {
            System.Threading.Monitor.Enter(swWrite);
            swWrite.WriteLine(sMessage + "     " + DateTime.Now.ToString("yyyy-MM-dd   HH:mm:ss"));
            swWrite.Flush();
        }
        finally
        {
            System.Threading.Monitor.Exit(swWrite);
        }
    }
    #endregion
}

#8


不懂,但我帮顶!

#9


忘记接分了!

#10


Dispose  如果你不是手工调用,就要等.net的回收机制调用才调用
========
不要误导,gc不会主动调用dispose 

#1


我是楼主~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MSDN上说的是Dispose释放托管资源,析构函数释放非托管资源.

推荐这种写法

我这里提供的是静态方法.

而程序里调用这个方法是多线程的.

所以也不可能用using.

#2


up

#3


up

#4


lz 没有理解对象实例和类的区别
dispose 也好 析构函数也好,都是针对某个具体的对象,而不是针对一个类型

#5


Dispose  如果你不是手工调用,就要等.net的回收机制调用才调用

#6


你强制进行GC.Collect

#7


LZ的这一段问题还真不少:
1、Dispose,Finnalize,这些只对实例对象,不是对Class的。LZ就没有实例化过任何对象,所以Log.AddLog("抓取数据结束");这一句一直不会被执行。
2、LZ使用了静态实例对象Stream,没有最终Close。


解决方案:

public class Log
{
    private static readonly StreamWriter swWrite;

    static Log()
    {
        swWrite = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + System.DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");

        Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
    }

    static void Application_ApplicationExit(object sender, EventArgs e)
    {
        Log.AddLog("抓取数据结束");

        swWrite.Dispose();
        swWrite = null;
    }

    #region   记录日志
    public static void AddLog(string sMessage)
    {
        try
        {
            System.Threading.Monitor.Enter(swWrite);
            swWrite.WriteLine(sMessage + "     " + DateTime.Now.ToString("yyyy-MM-dd   HH:mm:ss"));
            swWrite.Flush();
        }
        finally
        {
            System.Threading.Monitor.Exit(swWrite);
        }
    }
    #endregion
}

#8


不懂,但我帮顶!

#9


忘记接分了!

#10


Dispose  如果你不是手工调用,就要等.net的回收机制调用才调用
========
不要误导,gc不会主动调用dispose