如何正确使用实现IDisposable的静态属性?

4
作为一个例子:
using (Brushes.Black)
{
...
}

静态资源不是一个好主意,因为它是静态的。 下次您的应用程序使用Brushes.Black时,您会遇到问题,因为它已被处理。

现在,如果您只使用Brushes.Black,则可能可以不处理它,因为您只留下了一个未管理的资源(希望如此!)。

但是,一般来说,您应该避免使用大量静态IDisposable,或者我忽略了什么?

2个回答

3

通常只需使用它们,让框架类负责处理它们的释放。

它们存在的目的是让您无需每次创建和释放它们即可使用。每个对象在首次使用时创建,并缓存到哈希表中。应用程序关闭时,框架类负责适当地释放它们。

实际上并没有那么多静态IDisposable对象需要您担心。如果您要使用大量画刷,则可能会在循环中从颜色创建它们(然后您当然要负责释放它们)。


我很惊讶你没有得到任何关于这个的评论。 通常人们对于始终处理IDisposable对象有很强烈的感觉。 但是,我想在静态IDisposable的情况下,指导方针应该是“不要处理它们,也不要使用大量的它们”。 - mbeckish
1
你应该处理自己拥有的对象,但由于Brushes类拥有Brush实例,因此你不能处理它们。这样做会使Brushes类包含对不可用对象的引用。 - Guffa

2
作为一个例子: 使用(Brushes.Black){...}不是一个好主意,因为它是静态的。下一次你的应用程序使用Brushes.Black时,你会遇到问题,因为它已经被处理了。 这不仅仅是一个静态字段——该属性在需要创建新实例时积极运行代码。只需查看相应代码(Reflector)。
public static Brush Black
{
    get
    {
        Brush brush = (Brush) SafeNativeMethods.Gdip.ThreadData[BlackKey];
        if (brush == null)
        {
            brush = new SolidBrush(Color.Black);
            SafeNativeMethods.Gdip.ThreadData[BlackKey] = brush;
        }
        return brush;
    }
}

当我在紧密循环中使用(Brushes.Black){...}时,实际上遇到了问题 - 也许它没有立即设置为null? - mbeckish
+1 一次性对象应该由其所有者进行处理。这段代码来自反射器,显示调用者是所有者。 - Wim Coenen
@wcoenen - 我同意你在谈论自己本地对象实例时的观点。但是,由于这是静态的,您必须能够保证将来应用程序中的任何代码都不需要在安全处理之前使用它。现在,根据Reflector的说法,在这种情况下,这不应该是一个问题,因为如果刷子为空,它会创建一个新的刷子。然而,正如我在对此答案的第一条评论中提到的那样,如果您只使用“using”语句而没有明确将其设置为null,它似乎并不总是起作用。 - mbeckish
2
@mbeckish:释放对象永远不会将引用设置为null,所以Brushes类将不知道它必须重新创建对象。@wcoenen: 不,调用者不是所有者,Brushes类是所有者。它保持对对象的引用。 - Guffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接