Bill Robertson's Blog

IDisposable on a Struct

The ReaderWriterLock is an excellent thread syncing object.  Instead of having a single lock() statement that control access, it will allow simultaneous reads, but retain blocking writes.  It becomes very useful through a singleton object where you have several reads, but very few writes.  I find the syntax a little cumbersome though.

try
{
 myLock.AcquireReaderLock( 1000 );
 DoLockedRead();
}
finally
{
 myLock.ReleaseReaderLock( 1000 );
}

Some time back I created a wrapper around the lock that simplifies the syntax slightly.  This greatly simplifies the locking syntax using my favorite C# syntax…the using statement.

using( new RWReader( myLock ) )
{
 DoLockedRead();
}

I created the wrapper class as a class.  By default all Types I create always start out as classes unless I have a reason to use a value type.  Mostly it is because I don’t want my object to be a value type and copy it from method to method and end up memcpy the entire stack from frame to frame, but there are times structs are useful.

Recently I used this wrapper in a situation where I was inside a tight loop.  I know when you “new” up an object it creates the object and places it on the managed heap, so it can be garbage collected later.  However, inside a tight loop it probably isn’t good to go wailing on the managed heap when a struct might work.

The question I am unsure of is since I am implementing IDisposable on the struct, is the struct going to be boxed anyway thus added extra overhead as the stack memory must be boxed and placed on the managed heap.  I know I should just use CLR profiler and see what is happening with allocations, but I have never used it, only read about it.

Any thoughts?

Comments

Eric Lippert said:

A call to IDisposable.Dispose on a struct is generated as a constrained virtual call, which most of the time does NOT box the value.

A constrained virtual call on a value type only boxes the value if the virtual method is NOT implemented by the type.  The only circumstances under which a virtual method can be unimplemented by the value type is when the method is, say, ToString, and implemented by the base class, System.ValueType.

See section 2.1 of Partition III of the CLI documentation for more detail.

# June 1, 2007 5:21 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)