Sunday, December 19, 2010

Wrong answer #1: Your own ThreadLocal

Well, one way we can use to solve the problem is by introducing a finalizer, like so:

public class CloseableThreadLocal
{
   [ThreadStatic] private static Dictionary<object, object> slots;
   public static Dictionary<object, object> Slots
   {
       get { return slots ?? (slots = new Dictionary<object, object>()); }
   }
   public /*protected internal*/ virtual Object InitialValue()
   {
       return null;
   }
   public virtual Object Get()
   {
       object val;
       if (Slots.TryGetValue(this, out val))
       {
           return val;
       }
       val = InitialValue();
       Set(val);
       return val;
   }
   public virtual void Set(object val)
   {
       Slots[this] = val;
   }
   public virtual void Close()
   {
       GC.SuppressFinalize(this);
       if (slots != null)// intentionally using the field here, to avoid creating the instance
           slots.Remove(this);

Read more: Ayende @ Rahien