I have a class that implements IDisposable
, because it uses image resources (Bitmap
class) from GDI+. I use it for wrapping all that gimmicky LockBits
/UnlockBits
. And it works fine, be it when I call Dispose()
or with the using
statement.
However, if I leave the program to terminate without disposing, I get a System.AccessViolationException
. Intuitively, I think the GC would call the Dispose
the same way I do, and the object would gracefully release the resources, but that's not what happening. Why?
Here's the IDisposable
code:
private bool _disposing = false;
~QuickBitmap() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool safeDispose) {
if (_disposing)
return;
SaveBits(); // private wrapper to UnlockBits
bytes = null; // byte[] of the image
bmpData = null; // BitmapData object
if (safeDispose && bm != null) {
bm.Dispose(); // Bitmap object
bm = null;
}
_disposing = true;
}
Here's when it works ok:
using (var qbm = new QuickBitmap("myfile.jpg"))
{
// use qbm.GetPixel/qbm.SetPixel at will
}
Here's when it doesn't work:
public static void Main (string[] args) {
// this is just an example, simply constructing the object and doing nothing will throw the exception
var qbm = new QuickBitmap(args[0]);
qbm.SetPixel(0, 0, Color.Black);
qbm.Save();
}
The complete excetion is (there's no inner exception):
An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
The reproduction is 100%, even on different machines. I do figure out we should use using
or Dispose()
, not using it is bad and all that stuff. I just want to know: why does this happen? Why is the memory "protected"? Which kind of access am I violating?