new Bitmap()正在抛出随机的、不可跟踪的异常

本文关键字:异常 跟踪 随机 Bitmap new | 更新日期: 2023-09-27 18:27:29

我在代码中有几个地方只是创建一个新的位图对象,如下所示:

bmpTile = new Bitmap(8, 8, PixelFormat.Format32bppArgb);

很简单,对吧?出于某种原因,我随机地在这样的行上得到异常。所谓随机,我的意思是,在相同的事件序列之后,我不能在同一行上一致地再现相同的异常。我甚至不能创建一个单元测试给你们看。

我遇到的最常见的异常是:

ArgumentException: Parameter is not valid.
TargetSite: {Void .ctor(Int32, Int32, System.Drawing.Imaging.PixelFormat)}

接下来最常见的一个甚至没有给我程序内部的堆栈跟踪:

AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
StackTrace:
    at System.Drawing.SafeNativeMethods.Gdip.IntGdipDisposeImage(HandleRef image)
    at System.Drawing.SafeNativeMethods.Gdip.GdipDisposeImage(HandleRef image)
    at System.Drawing.Image.Dispose(Boolean disposing)
    at System.Drawing.Image.Finalize()
TargetSite: {Int32 IntGdipDisposeImage(System.Runtime.InteropServices.HandleRef)}

每当我尝试创建新位图时,它似乎在处理旧位图时遇到了问题,但为什么?我普遍使用LockBits和UnlockBits,但我总是成对使用:我从不在没有后续UnlockBit的情况下调用LockBits。

那么,是什么导致Dispose()像这样失败呢?

编辑:我应该提一下,第二次尝试时没有发生这种情况。它发生在第五次或第六次尝试时,这意味着它已经毫无问题地处理了前四个或五个位图。

new Bitmap()正在抛出随机的、不可跟踪的异常

这两个问题都有相同的根本原因。LockBits()之后的代码正在损坏非托管堆。在这样的代码中通常使用指针或Marshal.Copy(),因此在位图边界之外写入时不会出现诊断。只有在运气好的情况下,您才会获得AccessViolation。但更常见的情况是,直到稍后堆分配器尝试从堆中分配或释放块失败时,您才会得到它们。很难诊断,因为崩溃位置与原始错误无关。