• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    基于自定义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.ResolveIExample>().SayHello();
            container.ResolveIExample>().SayHello();

            Actionint> action = delegate(int sleep)
            {
              container.ResolveIExample>().SayHello();
              Thread.Sleep(sleep);
              container.ResolveIExample>().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.ResolveIExample>();
          }

          example.SayHello();

          Console.ReadKey();
        }

    您可能感兴趣的文章:
    • 解决unity3d导入模型贴图材质丢失的问题
    • Unity使用EzySlice实现模型多边形顺序切割
    • Unity实现鼠标或者手指点击模型播放动画
    • Unity UI拖拽模型选择功能
    • Unity3D实现模型淡入淡出效果
    • Unity3D网格功能生成球体网格模型
    • Unity实现模型点击事件的方法
    上一篇:ASP.NET页面间数据传递的几种方法介绍
    下一篇:asp.net C#实现下载文件的六种方法实例
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    基于自定义Unity生存期模型PerCallContextLifeTimeManager的问题 基于,自定义,Unity,生,存期,