【问题标题】:If I replace an image in a PictureBox control, should I dispose the original image first?如果我替换 PictureBox 控件中的图像,我应该先处理原始图像吗?
【发布时间】:2010-04-10 12:03:27
【问题描述】:

从my question here开始,如果我替换图片框中的图像,我应该先处理原始图像吗?

或者,这种情况怎么办:

Dim bm As New Bitmap(32,32)  
bm = New Bitmap(32,32)  
bm = New Bitmap(32,32)  
bm = New Bitmap(32,32)  

bm 是否只需要在最后被释放,还是应该在每次重新创建之前释放?


感谢大家的回答。我有一个很大的疏忽。我知道一个控件会处理它的孩子,但我没有想到如果我替换旧图像,我应该处理它。

【问题讨论】:

    标签: c# .net vb.net winforms idisposable


    【解决方案1】:

    是的,您应该先处理旧对象,然后再在同一变量之上创建新图像。通过创建具有相同变量的新图像,您正在删除对它的引用。如果没有对旧对象的引用,则表示它应该由 GC(垃圾收集器)拾取。虽然从技术上讲,这个“应该”最终导致内存被释放,假设终结器确保非托管资源得到处理,这是一个很大的假设(你甚至不能真正假设终结器会被调用) ,它会为系统带来更多的工作。非默认终结器会在垃圾收集级别提升方面为 GC 带来额外的工作,从而导致释放内存所需的时间更长,以及 GC 必须运行的次数。

    这是假设所有这些都是为了确保终结器处理它而编写的。任何时候一个对象有一个 Dispose 方法(任何实现 IDisposable BitMap 的方法),都应该在删除对对象的引用之前调用它(超出范围,删除对对象的引用等)。

    这是一篇关于垃圾收集器如何在 .net 中工作的文章

    http://www.devx.com/dotnet/Article/33167

    下面是 MS 所说的 dispose / finalizer 应该如何实现的:

    http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx

    【讨论】:

      【解决方案2】:

      当更改与PictureBox 关联的图像时,当且仅当没有其他人会使用该图像时,才应该对存在的图像调用Dispose。要知道这一点,就必须知道旧图像的来源。在某些情况下,创建图像只是为了分配给PictureBox。在其他情况下,图像可能是旨在共享和/或重用的图像。如果创建图像只是为了分配给PictureBox,如果PictureBox 被处置或赋予另一个图像,则它应该是Disposed。如果图像应该被共享或重复使用,则此类条件不得导致其被丢弃。

      一般来说,解决此类问题的正确方法是让具有IDisposable 属性的类(如PictureBox,具有Image)使用显式SetImage 方法而不是具有可变Image 属性,并且SetImage 方法包含一个参数,该参数指示PictureBox 是否应承担处置它的责任。在 PictureBox 上调用 SetImage 或 Dispose 当且仅当先前的 SetImage 调用赋予它该责任时,才应在所持有的图像上调用 Dispose。不幸的是,PictureBox 不能以这种方式工作,但我强烈建议您将其用作未来编写的包含 IDisposable 对象的类的模式。

      【讨论】:

      • 这是关于问题第一部分的唯一答案,关于是否在分配之前处理PictureBox 的图像。
      • @UweKeim:我认为这是一个其他答案都没有涉及的重要问题。很高兴您发现我的回答很有帮助。我怀疑必须在人们真正弄清楚 IDisposable 将如何工作之前编写框架,并且那些旧类是一成不变的,但是没有理由新的类应该重复旧的错误。
      【解决方案3】:

      是的,你应该这样做。它实现了 IDisposable。
      作为一般经验法则,处置所有实现 IDisposable 的对象。不要把它留给 GC。

      【讨论】:

        【解决方案4】:

        bm 是只需要在最后处理,还是应该在每次重新创建之前处理?

        它应该在每次“娱乐”之前被丢弃。不要将对象与对象引用混淆。 “新位图”创建一个新对象。 “bm”是恰好指向该对象的引用。她们不一样。您不是在这里“重新创建”任何对象 - 您正在创建一个新对象,然后删除对前一个对象的所有引用,这意味着我将在(不久的)将来的某个时间被垃圾收集。

        【讨论】:

        • 感谢您为我解决这个问题。我知道您回答中的所有概念,但有些日子我大脑冻结了!曾经忘记如何拼写一个简短的单词?就是这种感觉。
        猜你喜欢
        • 2011-09-02
        • 1970-01-01
        • 2011-10-28
        • 1970-01-01
        • 2018-03-27
        • 1970-01-01
        • 2012-02-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多