Posted by: Zeeshan Amjad | February 29, 2012

Disposable GCHandle


GCHandle is a structure use to store handle for unmanaged objects, such as COM+ or we want to access the memory from unmanaged code too. In addition we can create a GCHandle to create a strong reference that garbage collector can not collect, weak reference, that can be collected from garbage collection or pinned object whose actual address (virtual address) can be taken and can not be moved anywhere from garbage collection. There is one enum GCHandleThype passed at the time of creation of GCHandle to specify the type of GCHandle. Here is a diagram of GCHandleType enum.

GCHandleType

 

Here is a class diagram of GCHandle.

GCHandle

GCHandle doesn’t implement the IDisposable interface, therefore we can’t use it with C# using statement. Let’s create a small wrapper on this class to implement the Disposable pattern.

We created a simple class that calls the GCHandle methods internally. Here is our first attempt to create a wrapper.

Code Snippet
public class DisposableGCHandle
{
    private GCHandle handle;

    public DisposableGCHandle(Object value)
    {
        this.handle = GCHandle.Alloc(value, GCHandleType.Normal);
    }

    public DisposableGCHandle(Object value, GCHandleType type)
    {
        this.handle = GCHandle.Alloc(value, type);
    }

    public IntPtr AddrOfPinnedObject()
    {
        return this.handle.AddrOfPinnedObject();
    }

    public void Free()
    {
        this.handle.Free();
    }  
}

 

Similarly we created IsAllocated and Target properties that simply delegate the call to GCHandle object.

Code Snippet
public Object Target
{
    get { return this.handle.Target; }
    set { this.handle.Target = value; }
}

public bool IsAllocated
{
    get { return this.handle.IsAllocated; }
}

 

Then we inherit our new wrapper class from IDisposable and implement that interface. We also added Close method while implementing the Disposable design pattern that method is identical to Dispose method.

Here is a complete code of our Disposable GCHandle class.

Code Snippet
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;

[SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class DisposableGCHandle : IDisposable
{
    private GCHandle handle;

    public DisposableGCHandle(Object value)
    {
        this.handle = GCHandle.Alloc(value, GCHandleType.Normal);
    }

    public DisposableGCHandle(Object value, GCHandleType type)
    {
        this.handle = GCHandle.Alloc(value, type);
    }

    public IntPtr AddrOfPinnedObject()
    {
        return this.handle.AddrOfPinnedObject();
    }

    public void Free()
    {
        this.handle.Free();
    }

    #region Properties

    public Object Target
    {
        get { return this.handle.Target; }
        set { this.handle.Target = value; }
    }

    public bool IsAllocated
    {
        get { return this.handle.IsAllocated; }
    }

    #endregion

    #region DisposePattern

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (handle.IsAllocated)
            {
                this.handle.Free();
            }
        }

        GC.SuppressFinalize(this);
    }

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

    public void Close()
    {
        this.Dispose(true);
    }

    ~DisposableGCHandle()
    {
        this.Dispose(false);
    }

    #endregion
}

Advertisements

Responses

  1. […] writing one wrapper on top of GCHandle that implement IDisposable interface and Disposable pattern here. But one can argue that it is a structure, i.e. value type, and it is not allocated in heap, so […]

  2. Thanks! But question: Does this violate the following article, especially the last “IDisposable” section?
    http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx

    • Yes it does. Thanks for pointing out this. The purpose of this article is to make a ground for IDisposable WeakReference. WeakReference is a class type not like GCHandle a structure. So it would make more applicable in WeakReference rather than GCHandle class.

      Thanks for visiting my blog and post comment here.

      Regards
      Zeeshan Amjad


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: