2009-09-10 85 views
1

是否需要手动管理System.Drawing对象的生命周期?处理System.Drawing对象

目前,我正在使用'using'语句来最大限度地减少画笔和其他绘图对象的使用寿命,例如

using (Brush br = new SolidBrush(color)) 
{ 
    // Do something with br 
} 

这是必要的还是安全的让垃圾收集器工作时,如果它的魔法需要?

作为一个快速抛开这个问题......人们认为什么是最简单的方法来实现这一目标?

回答

2

它是处置System.Drawing对象,但是如果您错过了一个或者当你得到一个异常等两个,这不是世界末日。 (其他对象像打开的文件和数据库连接必须始终处理

在您的代码中使用大量“使用”语句会使其更加复杂。因此,我想在System.Drawing对象的情况下,考虑只是在方法的末尾调用Dispose()。

在过去,我使用了一个我编写的“Dustcart”类,它实现了IDisposable,并且包含了要处理的对象集合。然后,您可以编写如下代码:

using(var dustcart = new Dustcard()) 
{ 
    var p = dustcart.Add(new Pen(red, etc)); 
    var b = dustcart.Add(new Brush(black)); 

    Pen t; 
    if (someFlag) 
    { 
     t = p; 
    } 
    else 
    { 
     t = dustcard.Add(new Pen(etc)); 
    } 
} 
+0

我喜欢这个想法,即通过处置垃圾车,你可以处理其中的所有物品!我认为这是我要去尝试和记住下一次我需要考虑管理对象的使用寿命的一些事情。不过,我想这只会在您看到大量需要处理的嵌套使用语句或多个对象时才有意义。 – 2009-09-28 07:17:39

+0

@Tk,当您有条件地创建新对象或重新使用现有对象时,它非常有用。当简单的“嵌套使用语句”是不够的。在简单的情况下,“使用”是最好的,因为每个人都知道它的含义 – 2009-10-08 21:59:02

2

一般的经验法则是,如果一个对象实现了IDisposable,你需要清理它。 IDisposable没有在.NET Framework中随心所欲实现 - 有充足的理由让它在那里。

10

当一个对象是IDisposable时,那么最好在你不再需要时立即处理它。 (由于某种原因它实现了IDisposable)。

当您忘记调用Dispose时,垃圾收集器将在某个时间完成它的工作并清理它,这样资源就会被释放,但您无法分辨或猜测垃圾收集器何时会启动,这不是确定性的。

所以,我的建议是:一旦你不再需要一次性物品,手动处理(就像你现在所做的那样)。

1

正如其他人所说:当你创建一个IDisposable对象时,你应该尽快处理它。在您的具体示例中,如果在编译时已知颜色,则可以使用标准笔刷,例如Br​​ush br = Brushes.Blue,您不需要处理该笔刷。

+1

我喜欢使用预定义对象(如Brushes.Blue)的观点。这也更有效率,因为你不必实例化一个新对象并浪费内存。 – dotnetengineer 2015-04-21 21:00:45

1

如果反复使用相同的颜色,可以将笔刷存储为类级别的成员,但这意味着拥有的类别也应该是IDisposable,并将刷子成员置于其处理方法中。 这会增加内存的存储空间(按一个笔刷的大小),但可能会减少代码量(不使用语句,而是额外的Dispose覆盖)。

+0

我很喜欢这个想法,不幸的是,我已经决定将所有这些绘图功能抽象为支持类型的类。因此,支持职能没有“所有者”,这意味着最终处置仍然是一个问题。再加上这些函数可以从多个线程访问的事实意味着添加类级别的变量可能最终会变得更加麻烦,那么它的价值! – 2009-09-10 10:10:52

0

我正在使用'using'语句,正如您在问题中所描述的一样,以保证Brush,Pen,Font,任何资源都能正确处理。在我的代码中,我发现使用语句比分散显式的.Dispose()调用更清洁。但这只是我的偏好。

我同意上面的答案:不管你喜欢使用语句还是使用.Dispose调用,手动清理资源非常重要,而不是依靠垃圾回收器。 (我刚开始依赖垃圾回收器,性能问题开始浮现,甚至在应用中的事情变得复杂之前)。