简体   繁体   English

静态一次性物体

[英]Static disposable objects

  • How should I manage static classes with disposable items? 我该如何使用一次性物品管理static类? Are there any rules of thumb? 有没有经验法则?

  • Basically, should I refactor and make the following DisposableDataManager class non- static or is it fine to leave everything to GC ? 基本上,我应该重构并使以下DisposableDataManagernon- 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();        
    }

    // ...
}

It really depends on how important it is to you that the resources are disposed. 这实际上取决于资源处置对您的重要性。 When your application closes, all handles it had open (files, network connections, graphics etc) will be released anyway, so that's not a problem. 当您的应用程序关闭时,它打开的所有句柄(文件,网络连接,图形等)都将被释放,所以不是问题。 It's more of a problem if you want disposal for a more orderly release - eg flushing a stream before closing it. 如果你想要一个更有序的发布处理,那就更成问题了 - 例如在关闭它之前冲洗流。 The CLR makes a "best effort" to run finalizers before the process exits, which will in turn call Dispose in some cases - but that's not something I'd want to rely on for anything important. 在进程退出之前,CLR会尽最大努力运行终结器,在某些情况下会调用Dispose - 但这并不是我想要依赖的重要事项。

So in the case of ImageList objects, it really shouldn't be an issue. 因此,对于ImageList对象,它确实应该不是问题。 You definitely won't leak any resources - the operating system will take care of that. 你绝对不会泄漏任何资源 - 操作系统将负责这一点。

Having said that, I'd still try to refactor - simply because global state tends to be a bad idea. 话虽如此,我仍然试图重构 - 仅仅因为全球状态往往是一个坏主意。 It makes dependencies implicit, and testing harder. 它使隐含的依赖性和测试更加困难。 How hard would it be to provide the relevant information to each object that needed it at construction time? 在施工时向每个需要它的物体提供相关信息有多难?

(Note: static variables are really associated with an AppDomain rather than the process as a whole. This makes the whole question more complex in applications where AppDomain s are brought up and down, but I doubt that it's relevant to your scenario.) (注意:静态变量实际上与AppDomain相关联,而不是整个过程。这使得整个问题在AppDomain启动和关闭的应用程序中更加复杂,但我怀疑它与您的场景相关。)

as a static class you are saying that everything is available to the application. 作为静态类,您说应用程序可以使用所有内容。 So why would you ever want to dispose of it? 那你为什么要把它丢弃呢?

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

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

I believe your current way of working may work, but there are definitely better ways of solving what ever your program is intending to do. 我相信你目前的工作方式可能有用,但肯定有更好的方法来解决你的计划打算做什么。 If it does work, it would be an abuse of the language - using features against what they were intended to be. 如果它确实有效,那就是滥用语言 - 使用功能来反对它们的目的。

If you continue on this architecture path, your code will be difficult to understand and modify. 如果继续使用此体系结构路径,则代码将难以理解和修改。

It would probably be worth writing up what you're after with this method and ask for alternative ideas. 用这种方法写出你所追求的内容并提出其他想法可能是值得的。

Disposable resources should never be held in a static class anyway. 无论如何,永远不应该在静态类中保存一次性资源。 Since they are unlikely to be disposed if the program ends (for instances if the program crashes). 因为如果程序结束它们不太可能被处理(例如程序崩溃的情况)。 So you have the possibility to add and release the resources yourself in an object which will be existent as long your application runs and 因此,您可以在一个对象中自行添加和释放资源,只要您的应用程序运行,该对象就会存在

  • is wrapped in a using statement before entering your program loop. 在进入程序循环之前,它被包装在using语句中。
  • or you take care of it by yourself, and calling the dispose in a finally construct as soon as your program ends. 或者你自己照顾它,并在程序结束后立即调用处理器。

Or you may change the ImageList to be not be disposable at all. 或者您可以将ImageList更改为根本不可丢弃。 This would be an option only if you can dispose all resources it holds by yourself. 只有当您可以自行处理它拥有的所有资源时,这才是一个选项。

I don't think that you need to do any disposable objects manager. 我认为你不需要做任何一次性对象管理器。 GC already manage memory for you. GC已经为您管理内存。 As you probably already know, Dispose method is the one coming from the IDisposable interface include in .Net framework. 您可能已经知道,Dispose方法是来自IDisposable接口的一个包含在.Net框架中的方法。 But it's a method like any one else*. 但这是一种像其他人一样的方法*。 The garbage collector don't wait that Dispose to be called to free the memory of an object. 垃圾收集器不等待调用Dispose来释放对象的内存。 He monitor if the object is always reachable from somewhere or not. 他监视对象是否总是可以从某个地方到达。 This help him to determine which object are alive and which are dead. 这有助于他确定哪些物体存活,哪些物体死亡。

Before to continue read a bit about GC generation. 之前继续阅读有关GC生成的内容。 http://msdn.microsoft.com/en-us/library/ms973837.aspx http://msdn.microsoft.com/en-us/library/ms973837.aspx

I'm not sure, but when new() is call, and GC reach the capacity of the actual used generation, he clear the next generation "dead" objects. 我不确定,但是当调用new()并且GC达到实际使用的代的容量时,他清除下一代“死”对象。 Probably at other times that i don't. 可能在其他时候,我没有。 GC is such a mystic and mysterious implementation, because is probably rote in C++. GC是一个神秘而神秘的实现,因为它可能在C ++中死记硬背。 But you don't have to care about it. 但你不必关心它。

In some cases (mono-develop), I heard that you should care more about it. 在某些情况下(单声道开发),我听说你应该更关心它。 But not if you code in a Microsoft environment. 但如果您在Microsoft环境中进行编码则不行。

*I told: *我告诉:

method like any one else 像任何其他人一样的方法

but the using block give you the freedom to don't care to call Dispose method of IDisposable objects and call the method for you. 但是使用块让你可以自由地调用IDisposable对象的Dispose方法并为你调用方法。 The existing being of method Dispose is to release resources that needs to be released before stop using an object. Dispose方法的现有方法是释放在停止使用对象之前需要释放的资源。

ex: 例如:

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

            Console.WriteLine("Disposed");
        }
    }


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

        }
    }

same as: 如同:

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

So you can be confident about GC. 所以你可以对GC充满信心。 If you want to be sure that GC will free you object memory, just make all references to it at null. 如果你想确保GC将释放你的对象内存,只需将它的所有引用都置为null。 And GC will consider your object as "dead" :P GC会将您的对象视为“死亡”:P

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM