欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-03 22:02:10
perthreadlifetimemanager的问题使用unity内置的perthreadlifetimemanager生存期模型时,其基于threadstatic的tl...

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();
    }

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