您的位置:首页 > 移动开发 > Unity3D

为Unity添加线程级别的生命周期管理

2013-01-09 11:16 441 查看

事情是酱紫的

  在当前项目中,用到了微软的unity依赖注入工具,原先项目代码是跑在WEB上的,从Kigg复制过来的代码自带了PerRequest级别的对象生命周期管理,结合Entity Framework和UnitOfWork、Repository模式,用起来没什么问题。可是后来,加了一个C/S结构的服务程序,为了代码复用,我把用于WEB上的程序集加了进来。这样一来,原先的PerRequest级别的对象生命周期管理肯定是不能用了,怎么办呢?我草率的把ObjectContext对象的生命周期搞成了singleton,可是跑了一段时间我就发现问题:服务器的数据库写是在多线程方式下运行的,而ObjectContest不是线程安全的,这显然不行。于是我想到,自己定义一个类似于PerRequest级别的生命周期管理--PerThread。

PerThread对象生命周期管理

  听名字就知道,这个对象生命周期管理是为同一个线程里的类型注入同一个对象实例的管理方式。因为手头有PerRequest的代码,所以模仿着写一个还是很容易的。我直接上代码。要是代码或想法有问题还请提出,平时写BS为主,对线程不熟。

/// <summary>
/// 线程级别生命周期
/// </summary>
public class UnityPerThreadLifetimeManager : LifetimeManager
{
private Thread _thread;
public UnityPerThreadLifetimeManager(Thread thread)
{
_thread = thread;
}
public UnityPerThreadLifetimeManager()
: this(Thread.CurrentThread)
{

}
public override object GetValue()
{
IDictionary<UnityPerThreadLifetimeManager, object> backingStore = BackingStore;
return backingStore.ContainsKey(this) ? backingStore[this] : null;
}

public override void RemoveValue()
{
throw new NotImplementedException();
}

public override void SetValue(object newValue)
{
IDictionary<UnityPerThreadLifetimeManager, object> backingStore = BackingStore;

if (backingStore.ContainsKey(this))
{
object oldValue = backingStore[this];

if (!ReferenceEquals(newValue, oldValue))
{
IDisposable disposable = oldValue as IDisposable;

if (disposable != null)
{
disposable.Dispose();
}

if (newValue == null)
{
backingStore.Remove(this);
}
else
{
backingStore[this] = newValue;
}
}
}
else
{
if (newValue != null)
{
backingStore.Add(this, newValue);
}
}
}

private IDictionary<UnityPerThreadLifetimeManager, object> BackingStore
{
get
{
_thread = (Thread.CurrentThread != null) ? Thread.CurrentThread : _thread;

return UnityPerThreadLifetimeManager.GetInstances(_thread);
}
}

private static IDictionary<Thread, IDictionary<UnityPerThreadLifetimeManager, object>> totalStore = new Dictionary<Thread, IDictionary<UnityPerThreadLifetimeManager, object>>();

internal static IDictionary<UnityPerThreadLifetimeManager, object> GetInstances(Thread thread)
{
IDictionary<UnityPerThreadLifetimeManager, object> instances;

if (totalStore.ContainsKey (thread ))
{
instances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[thread ];
}
else
{
lock (totalStore)
{
//删除已经结束的线程
IList<Thread> threads = totalStore.Keys.ToList();
for (int i = totalStore.Count - 1; i >= 0; i--)
{
Thread item = threads[i];
if (item.IsAlive == false)
{
IDictionary<UnityPerThreadLifetimeManager, object> removeInstances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[item];
foreach (var ins in removeInstances )
{
IDisposable dispose = ins.Value as IDisposable;
if (dispose != null)
dispose.Dispose();
}
totalStore.Remove(item);
}
}

if (totalStore.ContainsKey(thread))
{
instances = (IDictionary<UnityPerThreadLifetimeManager, object>)totalStore[thread ];
}
else
{
instances = new Dictionary<UnityPerThreadLifetimeManager, object>();
totalStore.Add(thread, instances);
}
}
}

return instances;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: