Posts
8
Comments
25
Trackbacks
0
ActionDisposable

I borrowed this class from the Wes Dyer's LINQ to ASCII Art post. It's a great way to return IDisposable from a method without creating a specialized class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace System {
 
    public class ActionDisposable: IDisposable {
 
        Action action;
 
        public ActionDisposable(Action action) {
            this.action = action;
        }
 
        public void Dispose() {
            action();
        }
 
    }
}

 

Wes uses ActionDisposable casually to reset Console properties. My example to demonstrate this class will be similar to Eilon Lipton's solution to locking a collection, expect I'll use ActionDisposable instead of specialized ReadLockDisposable and WriteLockDisposable.

public class SingletonSafeCollection<T>: Collection<T>
{
    private static readonly SingletonSafeCollection<T> instance = new SingletonSafeCollection<T>();
 
    public static SingletonSafeCollection<T> Instance {
        get
        {
            return instance;
        }
    }
 
    private ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
 
    /// <summary>Acquires a read lock for reading the collection</summary>
    /// <returns>Disposable object that releases the read lock</returns>
    public IDisposable GetReadLock()
    {
        rwLock.EnterReadLock();
        return new ActionDisposable(rwLock.ExitReadLock);
    }
 
    /// <summary>Acquires a write lock for writing the collection</summary>
    /// <returns>Disposable object that releases the write lock</returns>
    public IDisposable GetWriteLock()
    {
        rwLock.EnterWriteLock();
        return new ActionDisposable(rwLock.ExitWriteLock);
    }
 
}

 

Now I can use the SingletonSafeCollection<T> anywhere in my code with guarantees that when I one takes a read lock, no one will be writing to the collection and when one takes a write lock, no one will be writing to the collection.

 

static void Main(string[] args)
{
    SingletonSafeCollection<int> numbers = SingletonSafeCollection<int>.Instance;
    using (numbers.GetWriteLock())
    {
        // safe to write with a guarentee no one is reading or modifying the collection (except this thread)
        numbers.Add(1212);
    }
 
    using (numbers.GetReadLock())
    {
        // safe to read the list with a guarentee no one is modifying the collection
        numbers.ToList().ForEach(i => Console.WriteLine(i));
    }
 
    Console.ReadLine();
}

posted on Monday, May 26, 2008 2:32 PM Print
Comments
No comments posted yet.

Post Comment

Title *
Name *
Email
Url
Comment *  
Please add 7 and 2 and type the answer here: