C# 如果我不';t调用dispose()?

C# 如果我不';t调用dispose()?,c#,bitmap,dispose,C#,Bitmap,Dispose,我用这个代码来捕捉我电脑的屏幕 但是今天我发现有一个叫做Bitmap.Dispose()的方法 调用Dispose()与不调用Dispose()有什么区别?代码运行是否至关重要?必须调用Dispose。如果不这样做,则会有一些非托管资源(如GDI对象)无法清理。这意味着你会有内存泄漏 因此,是的,确实调用Dispose(或者更好,使用使用(…){…})。基本上,您的代码应该是这样的 public void screenShot(string path) { var

我用这个代码来捕捉我电脑的屏幕

但是今天我发现有一个叫做Bitmap.Dispose()的方法


调用Dispose()与不调用Dispose()有什么区别?代码运行是否至关重要?

必须调用
Dispose
。如果不这样做,则会有一些非托管资源(如GDI对象)无法清理。这意味着你会有内存泄漏


因此,是的,确实调用
Dispose
(或者更好,使用
使用(…){…}
)。

基本上,您的代码应该是这样的

    public void screenShot(string path)
    {
        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                        Screen.PrimaryScreen.Bounds.Height,
                                        PixelFormat.Format32bppArgb);

        var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                    Screen.PrimaryScreen.Bounds.Y,
                                    0,
                                    0,
                                    Screen.PrimaryScreen.Bounds.Size,
                                    CopyPixelOperation.SourceCopy);

        bmpScreenshot.Save(path, ImageFormat.Png);
    }
这可确保位图对象使用的非托管资源得到正确释放。使用一个位图,如果处理不当,您不会遇到真正的麻烦,但一旦开始批量处理,它就变得至关重要。不正确地处理将导致内存不足问题,我已经看到内存被不正确的编码很快填满。

Dispose方法来自“IDisposable”接口,并执行以下操作:

执行与释放、释放或重置非托管资源相关的应用程序定义的任务

基本上,您可以说所使用的资源不会立即释放。即使不再需要它们也不行。 但只有当垃圾收集器释放它们时

有关更多信息,请查看MSDN:

有关此主题的其他有用链接:


如果一个类型实现了
IDisposable
接口,那么您应该明确地调用
Dispose
方法(显式地或通过
使用
块)

如果我不调用dispose(),会发生什么

如果不这样做,析构函数(终结器)负责释放资源;但是,它有一些缺点:

  • 不确定:终结器由GC在专用线程上执行。GC决定何时运行它们。如果保留对对象的引用(例如,在主应用程序窗口中),则在退出应用程序之前,可能不会执行终结器
  • 开销:除非取消终结器,否则GC对要销毁的对象还有一些事情要做
  • 危险:如果终结器抛出异常,则认为该异常是致命的,并将使整个应用程序崩溃

阅读有关“垃圾收集器”的内容。许多.NET程序员在代码中从未使用过Dispose()。很少有好结果的.NET类是位图类。它们倾向于为像素数据占用大量非托管内存。当你创建了太多的屏幕截图。调用'Dispose()'或使用'using(…){…}'是否相同?@ArthurPark是的,它们严格等效。如上所述,
使用
是最好的,因为它已经实现了try/finally模式,因此即使抛出了一些异常,它也可以确保对象被释放。很抱歉,我们同时发布了我们的答案。这是正确的答案,我将删除我的。
public void screenShot(string path)
{
    using (var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                    Screen.PrimaryScreen.Bounds.Height,
                                    PixelFormat.Format32bppArgb))

    {
        var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                Screen.PrimaryScreen.Bounds.Y,
                                0,
                                0,
                                Screen.PrimaryScreen.Bounds.Size,
                                CopyPixelOperation.SourceCopy);

        bmpScreenshot.Save(path, ImageFormat.Png);
    }
}