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:
.NET, CSharp, Lambda