Создаем класс для хранения данных для рабочего потока (Thred Local Storage)

Иногда есть данные которые хочется сохранить для текущего рабочего потока и многие сохраняют их в HttpContext.Current.Items.  Но такой способ привязывает все приложение к asp.net mvc. Создадим класс TLS(Thread Local Storage), чтобы по возможности можно было использовать ThreadStatic или CallContext, в зависимости от режима TlsMode.

  1. public enum TlsMode
    {
        HttpContext, ThreadStatic, CallContext
    }
    public class TLS : ITLS
    {
        public TlsMode Mode { get; set; }
    
        [ThreadStatic]
        private static Dictionary<string, object> _data;
    
        public Dictionary<string, object> Data
        {
            get
            {
                if (Mode == TlsMode.HttpContext)
                {
                    if (HttpContext.Current.Items["TLS"] == null)
                        HttpContext.Current.Items["TLS"] = new Dictionary<string, object>();
                    return (Dictionary<string, object>)HttpContext.Current.Items["TLS"];
                }
                else if (Mode == TlsMode.ThreadStatic)
                {
                    if (_data == null)
                        _data = new Dictionary<string, object>();
                    return _data;
                }
                else
                {
                    if (CallContext.LogicalGetData("TLS") == null)
                        CallContext.LogicalSetData("TLS", new Dictionary<string, object>());
                    return CallContext.LogicalGetData("TLS") as Dictionary<string, object>;
                }
            }
        }
    
        public void Set(string name, object value)
        {
            Data[name] = value;
        }
        public object Get(string name)
        {
            if (!Contains(name))
                return null;
    
            return Data[name];
        }
        public T Get<T>(string name)
        {
            return (T)Get(name);
        }
        public T Get<T>(string name, bool create)
        {
            if (create && !Contains(name))
                Set(name, Activator.CreateInstance(typeof(T)));
            return (T)Get(name);
        }
        public bool Contains(string name)
        {
            return Data.ContainsKey(name);
        }
        public void Clear()
        {
            Dictionary<string, object> data = Data;
            if (data.Count == 0)
                return;
            foreach (var k in data.Keys)
                if (data[k] is IDisposable)
                    ((IDisposable)data[k]).Dispose();
    
            Data.Clear();
        }
    }
    
  2. Используем так
    TLS.Set("DbContext",  new DefaultDatabase()); // устанавливаем контекст бд
    TLS.Get<DefaultDatabase>("DbContext"); // получаем контекст бд
    
  3. Если в TLS хранятся объекты, для которых нужно освобождать ресурсы, то в Global.asax добавляем строчки
    protected void Application_EndRequest()
    {
        TLS.Clear();
    }
    

Создаем класс для хранения данных для рабочего потока (Thred Local Storage): Один комментарий

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>