The problem of Perthreadlifetimemanager
When using Unity's built-in Perthreadlifetimemanager lifetime model, it is based on the ThreadStatic TLS (Thread local Storage) design, which means that for each managed Managedthreadid, It caches the generated object instances.
Because the CLR maintains the managed thread pool, the used threads are not destroyed immediately and will continue to be reused when needed. In a similar asp.net percall or WCF percall condition, ManagedThreadId1 occurs when CALL1 is processed in the thread Call2, and Call2 is likely to be processed in the thread ManagedThreadId1 as well. Under this condition, Call2 automatically multiplexing object instances that are generated and cached when processing Call1.
Perthreadlifetimemanager is not appropriate in this scenario if we want to generate a dedicated object instance per invocation (Percall).
There are two ways to solve this problem:
1. Continue to use the Perthreadlifetimemanager model, do not apply to ThreadPool, and manually create and destroy threads.
2. Custom Object Lifetime Model
Percallcontextlifetimemanager
Copy Code code as follows:
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);
}
}
Use examples
Copy Code code as follows:
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 ();
}