我的Web应用程序中的每个请求都可以通过MVC3自己的依赖注入机制获得一个数据访问对象实例(类型为UnitofWork)。到目前为止一切都很好。
我正在创建一个Idisposable UnitofWorkScope对象来聚合这个数据访问对象上的一些商店调用,然后一起调用它们。实际上,UnitofWorkScope仅控制UnitofWork对象,该对象具有将存储添加到列表并稍后调用它们的功能。我相信UnitofWorkScope对象应该具有对数据访问对象的独占访问权限。
现在的问题:我想知道有人反对使用Monitor.Enter()在构造函数中获取的独占锁,然后使用Monitor.Exit在dispose方法中释放();
我通过描述我为什么要问这个问题来弄清楚水域,但我可以随意评论我在这里提出的任何问题。
public class UnitofWorkScope : IDisposable
{
public UnitofWorkScope(UnitOfWork UnitofWork)
{
if (UnitofWork == null)
{
throw new ArgumentException("UnitofWork argument null");
}
this._unitofWork = UnitofWork;
Monitor.Enter(_unitofWork); // obtaining exclusive access to the DAO of this request
this._unitofWork.AggregateDbChanges = true; //switched back off in dispose method
}
private readonly UnitOfWork _unitofWork;
bool _disposed;
public void Dispose(bool disposing)
{
if (!_disposed)
{
_unitofWork.CallFuncList();
Monitor.Exit(_unitofWork); //releasing the lock
_disposed = true;
GC.SuppressFinalize(this);
}
}
public void Dispose()
{
Dispose(true);
}
~UnitofWorkScope()
{
if (!_disposed)
{
Dispose(false);
}
}
}
这个想法就是像这样使用这个UnitofWorkScope:
UnitofWork _unitofWork = Resolver.GetService<UnitofWork>(); //gets the UnitofWork DAO
using (UnitofWorkScope UnitofWorkScope = new UnitofWorkScope(_unitOfWork))
{
// do a store
_unitofWork.Store<SomeClass>(_someInstance);
// do some more stores
try
{
UnitofWorkScope.Dispose(true);
}
catch (exception ex)
{
//try to undo those stores.
}
}
答案 0 :(得分:0)
是的,这对于实现锁定并不是一个糟糕的模式。但是:我建议稍微不同的Dispose版本,以保证即使_unitofWork.CallFuncList()
引发异常也会释放锁定,您依赖它来检测是否需要执行某种回滚。
private void Dispose(bool disposing)
{
if (!_disposed)
{
try
{
_disposed = true;
_unitofWork.CallFuncList();
}
finally
{
Monitor.Exit(_unitofWork); //releasing the lock
GC.SuppressFinalize(this);
}
}
}
但是,您可能希望从锁定“发布”逻辑中分离出“提交”,这样您就不必显式调用Dispose()
,而using语句将自动为您执行。
public void Commit()
{
_unitofWork.CallFuncList();
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
try
{
_disposed = true;
}
finally
{
Monitor.Exit(_unitofWork); //releasing the lock
GC.SuppressFinalize(this);
}
}
}
然后您可以像这样使用它:
using (var unitofWorkScope = new UnitofWorkScope(_unitOfWork))
{
// do a store
_unitofWork.Store<SomeClass>(_someInstance);
// do some more stores
try
{
unitofWorkScope.Commit();
}
catch (exception ex)
{
//try to undo those stores.
}
} // unitofWorkScope.Dispose() automatically called here