此代码中的内容导致C#中的内存泄漏?

Al *_*ger 2 c# memory-leaks

在Windows任务管理器中,我发现我的程序的内存使用量在运行时会随着时间的推移而增加.内存泄漏是由下面的代码引起的.代码是循环迭代图像列表并根据MSDN中的代码示例调整它们的大小.似乎管理所有资源并使用.Dispose()释放.

foreach ( string file in files )
{
    image = Image.FromFile( file );

    Rectangle cropRect = new Rectangle( 0, 0, 1000, 1000 );
    Bitmap src = ( Bitmap ) image;
    Bitmap target = new Bitmap( cropRect.Width, cropRect.Height );

    using ( Graphics g = Graphics.FromImage( target ) )  
    {
        g.DrawImage( src, new Rectangle( 0, 0, target.Width, target.Height ),
                                        cropRect,
                                        GraphicsUnit.Pixel );
    }

    image.Dispose();
    image = Image.FromHbitmap( target.GetHbitmap() );
    src.Dispose();
    target.Dispose();
    image.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

有人可以建议请问这段代码中内存泄漏的原因是什么?

Luc*_*ski 9

来自以下文件GetHbitmap:

您负责调用GDI DeleteObject方法来释放GDI位图对象使用的内存.有关GDI位图的更多信息,请参阅Windows GDI文档中的位图.

然后,从以下文档FromHbitmap:

FromHbitmap方法制作GDI位图的副本; 因此,您可以DeleteObject在创建新图像后立即使用GDI 方法释放传入的GDI位图.

看起来很清楚...你需要打电话DeleteObject:

[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);
Run Code Online (Sandbox Code Playgroud)

正如SJoshi指出的那样,你应该使用using块来确保Dispose在异常的情况下被调用.该DeleteObject呼叫应该是一个内部的finally块,以获得同样效果.