我的代码中有几个地方我只是在创建一个新的 Bitmap 对象,如下所示:
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,但我总是成对使用它们:我从不在没有后续 UnlockBits 的情况下调用 LockBits。
那么什么会导致 Dispose() 这样失败呢?
编辑:我应该提一下,它不会在第二次尝试时发生。它发生在大约第五或第六次尝试时,这意味着它已经毫无问题地处理了前四或五个位图。
最佳答案
这两个问题的根本原因相同。 LockBits() 之后的代码正在破坏非托管堆。通常在此类代码中使用指针或 Marshal.Copy(),因此当您在位图边界之外写入时没有诊断。您只有在幸运时才会遇到 AccessViolation。但更常见的是,直到稍后堆分配器尝试从堆中分配或释放 block 时,您才会获得它们。很难诊断,因为崩溃位置与原始错误无关。
关于c# - new Bitmap() 抛出随机的、不可追踪的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9677248/