栈上局部Bitmap调用LockBits后,需用finally确保执行UnlockBits吗?
结论:必须用try-finally确保调用UnlockBits
别纠结MSDN示例的简化写法,实际生产代码里一定要加try-finally,原因如下:
- LockBits锁定的是GDI+底层的非托管资源,这部分资源不在.NET垃圾回收器的管辖范围内。虽然Bitmap是托管对象,但GC只会回收它的托管内存,不会自动解锁它锁定的非托管资源。
- 异常场景下,如果没finally块,
UnlockBits()根本不会执行,Bitmap会一直处于锁定状态。直到GC最终触发它的Finalize方法时才会解锁,但Finalize的执行时机完全不确定——可能几秒、几分钟甚至更久,这段时间里被锁定的资源会持续占用,可能导致GDI资源耗尽、其他操作该Bitmap的代码报错等问题。 - 就算你把Bitmap返回给调用方,调用方也可能不会立刻Dispose它,锁定的资源会一直被占用,风险很高。
正确的代码写法如下:
{ Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); BitmapData bmpData = null; try { bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bmp.PixelFormat); // do some processing } finally { if (bmpData != null) { bmp.UnlockBits(bmpData); } } return bmp; }
补充说明:MSDN的示例通常是为了演示核心功能,会省略异常处理这类工程化细节,不能直接照搬进生产代码。
内容的提问来源于stack exchange,提问作者meJustAndrew
相关产品推荐
相关产品推荐

