我正在开展一个项目,其中包含以下所有数据库逻辑(读取和写入):
using(Util.DbRun ()) {
// Code here
}
我去查找这个DbRun方法,发现了这个:
static readonly object dbWait = new object();
static public IDisposable DbRun ()
{
Monitor.Enter (dbWait);
return new Disposable (() => Monitor.Exit(dbWait));
}
class Disposable : IDisposable
{
private Action action;
private volatile bool disposed = false;
public Disposable (Action action)
{
if (action == null)
throw new ArgumentNullException ("action can't be null");
this.action = action;
}
#region IDisposable implementation
public void Dispose ()
{
bool run = false;
if (!disposed) {
lock (this) {
if (!disposed) {
run = true;
disposed = true;
}
}
}
if (run)
action ();
}
#endregion
}
我的问题是;这与一般的lock { /* code here */ }
构造相比如何?
答案 0 :(得分:1)
嗯,这是需要维护的额外代码,以及GC要处理的许多额外对象(尽管其中大多数会死在gen-0中,所以可能并不重要),以及许多额外的锁定句柄(可能在处置中使用Interlocked
而不是lock(this)
来缓解。
它也完全处理导致在当前编译器中引入Monitor.Enter(object, ref bool)
用法的非常不可能的边缘情况,{{3}虽然这可能会被添加。
但我最大的问题是:为什么?它解决了什么问题?什么是更好来证明存在的合理性?
如果我想以有效的理由来执行,那么我个人会废除委托使用,并编写一个自定义的,特定于实现的一次性对象。代表是不必要的复杂功能。
另外:静态锁并不总是你想要的。我会把它变成一个实例,只需将该实例提供给所需的地方。但是......相同的方法可以与lock
一起使用,更简单。