自定义Unity基于PerCall的生存期模型

简介:

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();
    }
复制代码







本文转自匠心十年博客园博客,原文链接:http://www.cnblogs.com/gaochundong/archive/2013/04/14/unity_per_call_context_lifetime_manager.html,如需转载请自行联系原作者

目录
相关文章
|
7月前
|
存储 图形学
浅谈Unity之模型裁剪shader
Unity之模型裁剪shader
|
7月前
|
图形学
浅谈Unity之ShaderGraph-模型膨胀流动
Unity之ShaderGraph-模型膨胀流动
|
8月前
|
图形学
【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)
【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)
348 0
|
10月前
|
API vr&ar 图形学
|
图形学
Unity 导入原神人物模型
Unity 导入原神人物模型
2688 2
Unity 导入原神人物模型
|
开发框架 图形学
Unity Hub 自定义一个创建新项目模板(Template)
Unity Hub 自定义一个创建新项目模板(Template)
385 1
Unity Hub 自定义一个创建新项目模板(Template)
|
图形学
Unity 模型中心点偏移问题解决方法
Unity 模型中心点偏移问题解决方法
940 1
Unity 模型中心点偏移问题解决方法
|
图形学 开发者
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
278 0
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
|
开发工具 图形学
“谁做虚拟仿真不得遇到个拆分模型呀”——分享如何使用Unity拆分3D模型
在仿真开发中,会遇到将模型进行移动、放大、旋转、拆分、合并等操作,其他的移动、放大、旋转都有比较多的例子进行参考,今天就分享一下如何将物体进行拆分