基于自定义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();
    }



相关阅读:
jquery实现不同大小浏览器使用不同的css样式表的方法
iOS中UIImagePickerController图片选取器的用法小结
iOS App的设计模式开发中对State状态模式的运用
javaweb实战之商城项目开发(二)
C++非递归建立二叉树实例
简单介绍C语言中的umask()函数和truncate()函数
win8.1关机变重启怎么办?Win8.1点了关机键却重启的解决办法介绍
Mongodb安装与配置笔记
jQuery选择器源码解读(三):tokenize方法
C# 邮箱mail 发送类
使用递归算法求第30位数的值
C# WinForm中禁止改变窗口大小的方法
win8.1系统电脑如何开启远程登录服务?win8.1系统开启远程登录服务的设置教程
JavaScript——DOM操作——Window.document对象详解
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 人鱼 岁月流去,还有孤独 血染的天空观影片南京大屠杀有感100字作文 迎新春,过大年 个性签名伤感超拽女生 弘一法师经典语录 小学六年级作文800字:水上新天堂 一年级数学工作小结 若弦不断,便可永安作文1400字 晨作文1400字 一滴水的旅程作文700字 2015年高考状元励志故事 大雪飞扬作文350字 黄昏里的浮云作文100字 班主任学习心得体会:桃李不言 下自成蹊 我是为你活着的 施特劳斯的『妙计』 摘一朵月光回家 党啊,母亲 交通局创先争优汇报材料 梦回乡间小路 少出力为“劣” 作风建设讲话 游宁波动物园 我的表姐苗苗 专工训练大队上的学兵代表发言 怀旧,而现在我该珍惜什么 那片天空有点儿涩I[拾伍](1)作文100字 过程与结果,怎样才完美? 2014年家长学校工作总结-学校工作总结_学校工作总结 一个人的故事,一个人的伤。 相逢是首歌 保护视力作文350字 一场球赛作文500字 打铁还须自身硬 冰岛奇遇 我家的老外 致我们的梦想 营销总监的辞职报告范本 钻石人生 父亲和祖父 “活力东风西,共圆中国梦”活动 法布尔作文500字 感叹刘恩沄 还是盲人好 最新社会工作实习报告范文 “小手牵大手 共营一片绿”活动倡议书 羊年同事圣诞节祝福语 生日祝福短信搞笑 听课心得体会:习作教学展示研讨课

Copyright © 2016 phpStudy |