Sunday, January 21, 2007

What is managed resources.

There have been enough posts about IDispose in .Net. The basically idea, to deterministically free up a resource, you need to implement the IDispose interface, also, it's better to offer a finalize method too.

Something like this:

MyResource:IDispose
{
~MyResource()
{
Dispose(false);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if(disposing)
{//clean up managed resources.
}
//clean up unmanaged resources.
}

So, my question is : what exactly is the unmanaged resources?

Are GDI+ objectes considered unmanged resources ? How about sockets, other windows resources ... ?

David Kline has a good example here :


using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Snippet
{
///
/// Wrapper for the Win32 Device Context (DC)
///
public class DeviceContext : IDisposable
{
// the Win32 Device Context (DC) object
private IntPtr hDC;

// window handle associated with the DC
private IntPtr hWnd;

///
/// Constructor.
///
///
/// The window handle for which to retrieve the device context
///
public DeviceContext(IntPtr hwnd)
{
// call the p/invoke to get the device context for the specified window handle
IntPtr hdc = GetDC(hwnd);

// verify that the GetDC call succeeded
if(hdc == IntPtr.Zero)
{
throw new Exception("Failed to get the DeviceContext for the specified window handle");
}

// store the window handle and device context for future reference
this.hWnd = hwnd;
this.hDC = hdc;
}

///
/// Finalizer
///
~DeviceContext()
{
// dispose the object (unmanaged resources)
this.Dispose(false);
}

///
/// Cleanup the object (implementation if IDisposable::Dispose)
///
public void Dispose()
{
// clean up our resources (managed and unmanaged resources)
this.Dispose(true);

// suppress finalization
// the finalizer also calls our cleanup code
// cleanup need only occur once
GC.SuppressFinalize(this);
}

///
/// Cleanup resources used by the object
///
///
/// Are we fully disposing the object?
/// True will release all managed resources, unmanaged resources are always released
///
protected virtual void Dispose(Boolean disposing)
{
if(disposing)
{
//*** release any managed resources
}

// release unmanaged resources
if(this.hDC == IntPtr.Zero)
{
// we're already been disposed, nothing left to do
return;
}
Int32 ret = ReleaseDC(this.hWnd, this.hDC);
this.hDC = IntPtr.Zero;
this.hWnd = IntPtr.Zero;

// assert if the DC was not released.
Debug.Assert(ret != 0,
"Failed to release DeviceContext.");
}

//*** add desired p/invoke definitions
}
}

Based on my experiences, most of the unmanaged resources have been already wrapped inside .Net class, and those are really should be treated like managed resources. For example, those objects defined in System.Drawing like bitmaps, fonts, meshes and textures, they are managed objects containing reference to unmanged resources.

No comments: