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: Collection

{

    private static readonly SingletonSafeCollection instance = new SingletonSafeCollection();

 

    public static SingletonSafeCollection Instance {

        get

        {

            return instance;

        }

    }


    private ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

    /// Acquires a read lock for reading the collection
    /// Disposable object that releases the read lock
    public IDisposable GetReadLock()
    {
       rwLock.EnterReadLock();
        return new ActionDisposable(rwLock.ExitReadLock);
    }


    /// Acquires a write lock for writing the collection
    /// Disposable object that releases the write lock
    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 numbers = SingletonSafeCollection.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();

}



Tags: , ,

posted on Monday, May 26, 2008 2:32 PM Print
Comments
No comments posted yet.
Title *
Name *
Email
Website
Comments (no HTML) *  
Please add 5 and 3 and type the answer here:
Posts
10
Comments
42
Trackbacks
0