• 自定义Unity生存期模型PerCallContextLifeTimeManager


    自定义Unity生存期模型PerCallContextLifeTimeManager

    PerThreadLifetimeManager的问题

    使用Unity内置的PerThreadLifetimeManager生存期模型时,其基于ThreadStatic的TLS(Thread Local Storage)设计,也就是说对于每个托管的ManagedThreadId,其会缓存已生成的对象实例。

    由于CLR维护了托管线程池,使用过的线程并不会立即销毁,在需要的时候会继续复用。在类似ASP.NET PerCall或WCF PerCall条件下,当Call1在线程ManagedThreadId1中处理完毕后,Call2发生,而Call2很有可能也在线程ManagedThreadId1中处理。这种条件下Call2会自动复用处理Call1时生成并缓存的对象实例。

    如果我们希望每次调用(PerCall)都生成专用的对象实例,则PerThreadLifetimeManager在此种场景下不适合。

    解决办法有两种:

    1. 继续使用PerThreadLifetimeManager模型,不适用ThreadPool,而手动创建和销毁线程。
    2. 自定义对象生存期模型

    PerCallContextLifeTimeManager

    复制代码
        public class PerCallContextLifeTimeManager : LifetimeManager
        {
          private string _key = 
            string.Format(CultureInfo.InvariantCulture, 
            "PerCallContextLifeTimeManager_{0}", Guid.NewGuid());
    
          public override object GetValue()
          {
            return CallContext.GetData(_key);
          }
    
          public override void SetValue(object newValue)
          {
            CallContext.SetData(_key, newValue);
          }
    
          public override void RemoveValue()
          {
            CallContext.FreeNamedDataSlot(_key);
          }
        }
    复制代码

    使用举例

    复制代码
        private static void TestPerCallContextLifeTimeManager()
        {
          IExample example;
          using (IUnityContainer container = new UnityContainer())
          {
            container.RegisterType(typeof(IExample), typeof(Example),
              new PerCallContextLifeTimeManager());
    
            container.Resolve<IExample>().SayHello();
            container.Resolve<IExample>().SayHello();
    
            Action<int> action = delegate(int sleep)
            {
              container.Resolve<IExample>().SayHello();
              Thread.Sleep(sleep);
              container.Resolve<IExample>().SayHello();
            };
    
            Thread thread1 = new Thread((a) => action.Invoke((int)a));
            Thread thread2 = new Thread((a) => action.Invoke((int)a));
            thread1.Start(50);
            thread2.Start(55);
            thread1.Join();
            thread2.Join();
    
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 50);
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 55);
            Thread.Sleep(100);
    
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 50);
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 55);
            Thread.Sleep(100);
    
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 50);
            ThreadPool.QueueUserWorkItem((a) => action.Invoke((int)a), 55);
            Thread.Sleep(100);
    
            example = container.Resolve<IExample>();
          }
    
          example.SayHello();
    
          Console.ReadKey();
        }
    复制代码

     
     
     
    标签: C#.NETWCFIoCDIUnity
  • 相关阅读:
    Linux学习33 crontab定时任务语法在线校验 上海
    python测试开发django175.bootstrap导航带下拉菜单的标签页标签页(navtabs) 上海
    python测试开发django172.jQuery 发送请求获取的数据设置为全局变量 上海
    team讨论有感
    蜕变(3)---模式
    uml建模的随想
    Bridge Strategy 和State的区别
    友元在模式中的运用
    Design&Pattern团队《设计模式在软件开发的应用》精华版
    面向对象乱弹(一)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3021163.html
Copyright © 2020-2023  润新知