静态一次性物体

时间:2012-08-23 13:20:07

标签: c# winforms static garbage-collection dispose

  • 我应该如何使用一次性物品管理static课程?有没有经验法则?

  • 基本上,我应该重构并制作以下​​DisposableDataManager课程non- static,还是将所有内容都留给GC

public static class DisposableDataManager
{
    // ImageList is an 'IDisposable'.
    public static ImageList FirstImageList { get; private set; }
    public static ImageList SecondImageList { get; private set; }

    static DisposableDataManager()
    {
        FirstImageList = CreateFirstImageList();
        SecondImageList = CreateSecondImageList();        
    }

    // ...
}

7 个答案:

答案 0 :(得分:14)

这实际上取决于资源处置对您的重要性。当您的应用程序关闭时,它打开的所有句柄(文件,网络连接,图形等)都将被释放,因此 不是问题。如果你想要更有序的发布处理,那就更成问题了 - 例如在关闭之前冲洗流。 CLR在流程退出之前“尽最大努力”运行终结器,然后在某些案例中调用Dispose - 但这不是我想要依赖的任何东西重要的。

因此,对于ImageList个对象,它确实应该不是问题。你肯定不会泄漏任何资源 - 操作系统会处理这个。

话虽如此,我仍然会尝试重构 - 仅仅因为全球状态往往是一个坏主意。它使隐含的依赖性和测试更加困难。在施工时向每个需要它的物体提供相关信息有多难?

(注意:静态变量实际上与AppDomain相关联,而不是整个过程。这使得整个问题在AppDomain被启动和关闭的应用程序中变得更加复杂,但是我怀疑它与你的情景有关。)

答案 1 :(得分:4)

作为静态类,您说应用程序可以使用所有内容。那你为什么要把它丢弃呢?

答案 2 :(得分:1)

您可以挂钩AppDomain.DomainUnload事件,并在退出前确定要清除的任何内容上调用dispose。

答案 3 :(得分:0)

我从该代码中看到的是,您将无法处置ImageList,因为DisposableDataManager是一个静态类,在应用关闭之前可以访问。

答案 4 :(得分:0)

我相信你当前的工作方式可能会工作,但肯定有更好的方法来解决你的计划打算做什么。如果它确实有效,那就是滥用语言 - 使用功能来反对它们的目的。

如果继续使用此体系结构路径,则代码将难以理解和修改。

用这种方法写出你所追求的内容可能是值得的,并且可以寻求其他想法。

答案 5 :(得分:-1)

无论如何,永远不要将一次性资源保存在静态类中。因为如果程序结束它们不太可能被处理(例如程序崩溃的情况)。因此,您可以在一个对象中自行添加和释放资源,该对象将在您的应用程序运行时存在并且

    在进入程序循环之前,
  • 被包装在using语句中。
  • 或者你自己照顾它,并在你的程序结束后立即调用处理器。

或者您可以将ImageList更改为不可丢弃。只有当您可以自己处理它拥有的所有资源时,这才是一个选项。

答案 6 :(得分:-1)

我不认为您需要做任何一次性对象管理器。 GC已经为您管理内存。您可能已经知道,Dispose方法是来自IDisposable接口的一个包含在.Net框架中的方法。但它是一种像其他人一样的方法*。垃圾收集器不等待调用Dispose来释放对象的内存。他监视对象是否总是可以从某个地方到达。这有助于他确定哪些物体存活,哪些物体死亡。

在继续阅读有关GC生成的内容之前。 http://msdn.microsoft.com/en-us/library/ms973837.aspx

我不确定,但是当调用new()并且GC达到实际使用的一代的容量时,他清除了下一代"死了"对象。可能在其他时候,我不会。 GC是一个神秘而神秘的实现,因为它可能在C ++中死记硬背。但你不必关心它。

在某些情况下(单声道开发),我听说你应该更关心它。但是如果您在Microsoft环境中进行编码则不行。

*我告诉:

  像任何其他人一样的

方法

但是使用块让您可以自由地调用IDisposable对象的Dispose方法并为您调用该方法。方法Dispose的现有方法是释放在停止使用对象之前需要释放的资源。

例如:

    public class Test : IDisposable
    {
        public void Dispose()
        {
            // release other necessary ressources if needed

            Console.WriteLine("Disposed");
        }
    }


    {
        using (IDisposable disposable = new Test())
        {

        }
    }

同样如下:

{
    IDisposable disposable = new Test()
    disposable.Dispose();
}

所以你可以对GC充满信心。如果你想确保GC将释放你的对象内存,只需将它的所有引用都置为null。 GC会将您的对象视为"死" :P