在应用程序关闭时将信息存储到文件的正确方法

时间:2012-07-17 19:11:28

标签: c#

我的一个类在应用程序执行期间收集统计信息,并且我希望在应用程序完成时将此统计信息存储到磁盘。我从来没有在我的程序中销毁这个类,所以我试图将日志存储到文件中:

    ~Strategy()
    {
        foreach(var item in statisticItems)
        {
            log.WriteLine(item.Text);    // log is AutoFlush
        }
    }

但是我没有看到我希望看到的日志,并且在析构函数调用时我也无法在调试器中“捕获”。

问题:

  • 为什么在调试器中我无法捕捉析构函数被调用的时刻?程序完成后,是否必须为每个对象调用析构函数?
  • 我应该用什么来记录我的东西?

3 个答案:

答案 0 :(得分:1)

析构函数(或终结器)不是放置代码的地方。它旨在释放非托管资源。析构函数是非确定性的,因此您不能依赖析构函数中的任何有效对象。并且您无法在调试器中捕获它,因为它在非常特殊的情况下在单独的线程上调用。简而言之,除非您知道需要,否则不要使用析构函数。

记录应用程序关闭的理想方法是简单地将日志记录代码放在Main方法的末尾。您应该确保捕获并记录引发的任何异常,如果是这种情况,您可以在Main结束时记录关闭。

由于堆栈溢出等错误,您将无法记录关闭的一些边缘情况。在这些情况下,您需要依赖于错误发生之前的日志。

答案 1 :(得分:-1)

不要依赖析构函数。我建议使用这样的东西:

[STAThread]
static void Main()
{
    using(new Strategy())
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

public class Strategy : IDisposable
{
    public void Dispose()
    {
        WriteLogs()
    }
    ...
}

这样您就可以确保写入日志了。

静态void Main是从创建Windows窗体应用程序时创建的默认program.cs中复制的。

答案 2 :(得分:-1)

不是一个完整的答案(还),但请查看:

  

程序员无法控制何时调用析构函数   因为这是由垃圾收集器决定的。垃圾   收集器检查不再被使用的对象   应用。如果它认为某个对象有资格进行销毁,那么   调用析构函数(如果有的话)并回收用于存储的内存   物体。程序退出时也会调用析构函数。

来源:MSDN

如果它是控制台应用,您是否可以尝试拨打Environment.Exit(0);来查看会发生什么?

让我们更新这个答案,因为这是一个有趣的问题。任何人都可以自由编辑。

此致