当处置是必要的?(When is Dispose necessary?)

2019-06-27 07:53发布

当你有这样的代码:

Bitmap bmp = new Bitmap ( 100, 100 );
Graphics g = Graphics.FromImage ( bmp );

Pen p = new Pen ( Color.FromArgb ( 128, Color.Blue ), 1 );
Brush b = new SolidBrush ( Color.FromArgb ( 128, Color.Blue ) );

g.FillEllipse ( b, 0, 0, 99, 99 );    
g.FillRegion ( b, pictureBox1.Region );

pictureBox1.BackColor = Color.Transparent;
pictureBox1.Image = bmp;

你有处置的画笔和画刷? 什么BMP和G?

我的主要问题是,如果这些都必须手动配置,他们为什么不得到尽快为他们走出范围的配置? 那是会发生什么,如果你没有手动处置它们? 难道让人手动执行此操作的延迟?

Answer 1:

是的,你必须处理它们-不仅仅是画笔和画刷,而且BitmapGraphics

他们时,他们超出范围,因为变量本身的引用,而不是对象,而C#编译器不知道是否所有权仍属于那些引用与否没有得到安置(如FillEllipse ,在理论上,还记得引用它给了,并尝试在稍后的某个时刻使用它 - !记住,语言编译器没有库语义的任何专业知识)。

如果你想表明,所有权限制在该范围内,可以使用using声明:

using (Bitmap bmp = new Bitmap ( 100, 100 ))
using (Graphics g = Graphics.FromImage ( bmp ))
using (Pen p = new Pen ( Color.FromArgb ( 128, Color.Blue ), 1 ))
using (Brush b = new SolidBrush ( Color.FromArgb ( 128, Color.Blue ) ))
{
    g.FillEllipse ( b, 0, 0, 99, 99 );    
    g.FillRegion ( b, pictureBox1.Region );
}

这将使得编译器插入调用来Dispose根据需要自动地,以确保一旦相应的所有对象被布置using范围被留下(是否正常,通过控制传递如returnbreak ,或异常)。

如果你来自一个C ++的背景下, using C#中直接类似于一个const std::auto_ptr ,不同之处在于它是一种语言结构,在这里,并且只能用于局部变量(即不属于类字段)。



Answer 2:

我知道其他人已经把代码示例在这里,但我开始,所以我会完成:

using (Bitmap bmp = new Bitmap(100, 100))
{
  using (Graphics g = Graphics.FromImage(bmp))
  {
    using (Pen p = new Pen(Color.FromArgb(128, Color.Blue), 1))
    {
      using (Brush b = new SolidBrush(Color.FromArgb(128, Color.Blue)))
      {
        g.FillEllipse(b, 0, 0, 99, 99);
        g.FillRegion(b, pictureBox1.Region);

        pictureBox1.BackColor = Color.Transparent;
        pictureBox1.Image = bmp;
      }
    }
  }
}

我总是用using在我的代码,因为它调用Dispose()的对象自动,即使在引发异常using块。 我用了很多的SharePoint项目(但这是另一个故事...)。



Answer 3:

C#不“破坏”或一旦他们走出去的范围的事情处理。

这些类很可能会自动释放,他们在他们的特殊抱到非托管资源Finalizer方法,当他们走出去的范围后,在一个不确定的时间收集的垃圾将被调用。

但是,依靠那就是依靠的东西,是你的控制,并且可能不会发生了一段时间。

如果该类实现IDisposable,最好的做法是,为您手动调用Dispose()某处,或优选地在包装它using块。 这样,你可以肯定的是:

答:非托管资源肯定被释放。

B.非托管资源被尽快释放。



Answer 4:

如果一次性模式被正确使用, Dispose 不是绝对必要的 -当对象被敲定将被调用,这样你就不会泄漏资源或任何东西。

然而,这是礼貌调用Dispose只要你正在使用的对象来完成,如一次性往往直接控制通常是有限的本机资源。 对象通常不会得到最终确定/收集向右走,所以这些资源都只是闲逛,白白浪费了,一旦你没有使用对象了。 立即处置的FreeS这些资源,这样他们就可以通过该程序(或在某些情况下,通过其他程序)的其他部分中使用。

请注意,一个using块自动销毁的对象,当你用它做,这就是为什么你很少,如果看到Dispose一个内using块。

短版:如果对象实现IDisposable ,和你的代码中创建它(即:如果它不是一个系统对象像Pens.BlueGraphics ,你得到通过OnPaint等),它应该当你完全符合做处置它-是否通过调用Dispose ,或者通过调用真实指定调用其他方法DisposeClose是一种常见的一种),或者通过使用一个using块。 你不必处置它,但你总是应该的。



Answer 5:

配置用于处置非托管资源。

所以,作为一个经验法则,我换了IDisposable对象的任何实例在using语句,所以我不担心什么非托管资源笔了。



Answer 6:

是的,BMP,G,B和P都是IDisposable的,你应该的Dispose()所有的人。 优选通过使用using() {}块。

当然也有例外,当您使用Pen p2 = Pens.Blue; 你要跟不应该处理P2。 这就是所谓的A股项目。 同为Brushes.Black等。

至于为什么 ,它是所有一次性类相同。 所以没有(不能)立即动作时的基准超出范围.NET不使用引用计数。

并把它留给垃圾回收器最终会释放他们,但它是(非常)低效。 我知道,失败的图形短缺处理,因为不及时处置他们一个ASP.NET(!)的应用。 它产生的图像。



文章来源: When is Dispose necessary?