C# 不会被处理的静态变量

C# 不会被处理的静态变量,c#,memory-management,memory-leaks,dispose,resource-management,C#,Memory Management,Memory Leaks,Dispose,Resource Management,我的类中有一个静态StreamWriter变量: private static StreamWriter streamWriter = CreateStreamWriter(pathToFile); 我不会在我的应用程序中关闭此StreamWriter,因为它需要在应用程序运行时打开 如果我多次启动和停止此应用程序,是否会出现内存泄漏?或者在关闭应用程序时对象是否已正确处理 此类是ASP.NET MVC 4和WPF应用程序都使用的实用程序类 谢谢大家的回复。以下是我添加的代码: 在包含Stre

我的类中有一个
静态StreamWriter
变量:

private static StreamWriter streamWriter = CreateStreamWriter(pathToFile);
我不会在我的应用程序中关闭此StreamWriter,因为它需要在应用程序运行时打开

如果我多次启动和停止此应用程序,是否会出现内存泄漏?或者在关闭应用程序时对象是否已正确处理

此类是ASP.NET MVC 4和WPF应用程序都使用的实用程序类

谢谢大家的回复。以下是我添加的代码:

在包含StreamWriter的类中:

public static void OnApplicationExit(object sender, EventArgs e)
{
    try
    {
        streamWriter.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
    }
    catch { }
}

public static void OnApplicationExit()
{
    try
    {
        streamWriter.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
    }
    catch { }
}
在ASP.NET MVC Global.Asax中:

    protected void Application_End()
    {
        Utilities.MyClass.OnApplicationExit();
    }

使用using语句,这是最好的方法

使用(var r=新的StreamWriter(,,){


}使用using语句,这是最好的方法

使用(var r=新的StreamWriter(,,){


}应用程序关闭时,不能保证处置
StreamWriter
。有时会,但在某些情况下这是不可能的

没有内存泄漏,因为它使用托管内存。当应用程序关闭时,将删除整个堆

这也不是资源泄漏,因为当应用程序关闭时,打开的文件句柄将被关闭


但是,
StreamWriter
有一个缓冲区,如果它没有被释放,就不会被刷新。这意味着您使用writer编写的最后的内容可能会从文件中丢失。

应用程序关闭时,不能保证将
StreamWriter
处理掉。有时会,但在某些情况下这是不可能的

没有内存泄漏,因为它使用托管内存。当应用程序关闭时,将删除整个堆

这也不是资源泄漏,因为当应用程序关闭时,打开的文件句柄将被关闭

但是,
StreamWriter
有一个缓冲区,如果它没有被释放,就不会被刷新。这意味着您使用writer编写的最后一些内容可能会从文件中丢失。

当您说“多次启动并停止此应用程序”时,您的意思是进程退出,并且每次都启动一个新进程吗?当一个进程退出时,它的所有内存都被操作系统回收,因此实际上没有“内存泄漏”

说到这里,我确实觉得在关闭时清理资源是一个好的做法;您可能决定要在同一进程内重新启动。修复泄漏比一开始就没有泄漏要困难得多

假设您必须在关机时执行其他操作,如刷新写入程序。然后,你需要某种在关机时启动的钩子。

当你说“多次启动并停止此应用程序”时,你的意思是进程退出并且每次启动一个新进程吗?当一个进程退出时,它的所有内存都被操作系统回收,因此实际上没有“内存泄漏”

说到这里,我确实觉得在关闭时清理资源是一个好的做法;您可能决定要在同一进程内重新启动。修复泄漏比一开始就没有泄漏要困难得多


假设您必须在关机时执行其他操作,如刷新写入程序。然后,您需要某种在关机时启动的钩子。

Streamwriter实现IDisposable。因此,如果不调用它的Dispose方法,就无法保证正确地处理了它的资源

在我看来,您有两个基本选择:

  • 保留StreamWriter的静态实例,但在应用程序关闭时捕获,然后调用StreamWriter.Dispose()释放资源。我不知道你的应用程序是WPF还是Windows窗体应用程序,但如果你能找到应用程序关闭时触发的事件,你可以在那里调用dispose。我想这可能是你需要的

  • 将StreamWriter转换为实例变量,使用using语句对其进行实例化,执行IO,然后立即将其处置:

    using(var writer = new StreamWriter())
    {
        //do your IO here
    }
    

  • 编辑:您指出您的应用程序是ASP.Net应用程序。对于ASP.Net应用程序,您可以在global.asax的应用程序开始事件中创建静态变量,并在global.asax的应用程序结束事件中处置静态变量。

    Streamwriter实现IDisposable。因此,如果不调用它的Dispose方法,就无法保证正确地处理了它的资源

    在我看来,您有两个基本选择:

  • 保留StreamWriter的静态实例,但在应用程序关闭时捕获,然后调用StreamWriter.Dispose()释放资源。我不知道你的应用程序是WPF还是Windows窗体应用程序,但如果你能找到应用程序关闭时触发的事件,你可以在那里调用dispose。我想这可能是你需要的

  • 将StreamWriter转换为实例变量,使用using语句对其进行实例化,执行IO,然后立即将其处置:

    using(var writer = new StreamWriter())
    {
        //do your IO here
    }
    
  • 编辑:您指出您的应用程序是ASP.Net应用程序。对于ASP.Net应用程序,可以在global.asax的application_Start事件中创建静态变量,并在global.asax的application_End事件中处置静态变量

    如果我多次启动和停止此应用程序,是否会出现内存泄漏

    否。当进程结束时,与进程关联的所有资源都会自动返回到操作系统。这是Windows的一个功能;这适用于所有流程,而不仅仅是托管代码流程

    正如其他人指出的,您可能会丢失数据,但不会泄漏内核对象

    是否在关闭应用程序时正确处理对象

    不一定。如果应用程序被“failing fast”终止,那么显然不会运行终结器,因为不会运行任何东西。如果应用程序被未处理的异常终止,则由实现定义终结器是否运行

    此外,正如Raymond Chen曾经指出的,当您知道