main
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Threading;
 5using gorilla.commons.utility;
 6
 7namespace gorilla.commons.infrastructure.threading
 8{
 9    public class PerThread : IContext
10    {
11        readonly IDictionary<int, LocalDataStoreSlot> slots;
12        readonly object mutex = new object();
13
14        public PerThread()
15        {
16            slots = new Dictionary<int, LocalDataStoreSlot>();
17        }
18
19        public bool contains<T>(IKey<T> key)
20        {
21            return key.is_found_in(get_items());
22        }
23
24        public void add<T>(IKey<T> key, T value)
25        {
26            key.add_value_to(get_items(), value);
27        }
28
29        public T value_for<T>(IKey<T> key)
30        {
31            return key.parse_from(get_items());
32        }
33
34        public void remove<T>(IKey<T> key)
35        {
36            key.remove_from(get_items());
37        }
38
39        IDictionary get_items()
40        {
41            var id = Thread.CurrentThread.ManagedThreadId;
42            within_lock(() =>
43            {
44                if (!slots.ContainsKey(id))
45                {
46                    var slot = Thread.GetNamedDataSlot(GetType().FullName);
47                    slots.Add(id, slot);
48                    Thread.SetData(slot, new Hashtable());
49                }
50            });
51            return (IDictionary) Thread.GetData(slots[id]);
52        }
53
54        void within_lock(Action action)
55        {
56            lock (mutex) action();
57        }
58    }
59}