13
  • 我应该如何管理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();        
    }

    // ...
}
4

7 回答 7

18

这实际上取决于处置资源对您的重要性。当您的应用程序关闭时,它打开的所有句柄(文件、网络连接、图形等)无论如何都会被释放,所以不是问题。如果您想处理更有序的发布,那就更成问题了——例如,在关闭流之前刷新它。DisposeCLR 会“尽最大努力”在进程退出之前运行终结器,在某些情况下这会反过来调用——但这不是我想要依赖的任何重要的东西。

所以在ImageList对象的情况下,它真的不应该是一个问题。你绝对不会泄露任何资源——操作系统会处理这些。

话虽如此,我仍然会尝试重构 - 仅仅是因为全局状态往往不是一个好主意。它使依赖关系变得隐含,并且更难测试。在施工时为每个需要它的对象提供相关信息有多难?

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

于 2012-08-31T06:06:46.907 回答
5

作为一个静态类,您是说应用程序可以使用一切。那么你为什么要处理它呢?

于 2012-08-23T13:28:44.410 回答
2

您可以挂钩 AppDomain.DomainUnload 事件并调用 dispose 在您想要确保在退出之前清理的任何内容。

于 2012-08-23T13:37:44.377 回答
0

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

于 2012-08-29T17:44:30.547 回答
0

我相信你目前的工作方式可能会奏效,但肯定有更好的方法来解决你的程序打算做的事情。如果它确实有效,那将是对语言的滥用 - 使用违背其意图的功能。

如果您继续使用此架构路径,您的代码将难以理解和修改。

用这种方法写下你所追求的东西并寻求其他想法可能是值得的。

于 2012-08-30T20:38:56.633 回答
-1

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

  • 在进入程序循环之前被包装在 using 语句中。
  • 或者您自己处理它,并在程序结束后立即在 finally 构造中调用 dispose。

或者您可以将 ImageList 更改为根本不是一次性的。仅当您可以自己处置它拥有的所有资源时,这才是一种选择。

于 2012-08-23T13:32:10.347 回答
-2

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

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

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

在某些情况下(mono-develop),我听说你应该更关心它。但如果您在 Microsoft 环境中编码,则不会。

*我说:

像其他人一样的方法

但是 using 块使您可以自由地不关心调用 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

于 2012-08-28T02:22:55.253 回答