以下构造与普通锁相比如何?

时间:2012-07-06 06:10:13

标签: c# concurrency locking

我正在开展一个项目,其中包含以下所有数据库逻辑(读取和写入):

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 */ }构造相比如何?

1 个答案:

答案 0 :(得分:1)

嗯,这是需要维护的额外代码,以及GC要处理的许多额外对象(尽管其中大多数会死在gen-0中,所以可能并不重要),以及许多额外的锁定句柄(可能在处置中使用Interlocked而不是lock(this)来缓解。

它也完全处理导致在当前编译器中引入Monitor.Enter(object, ref bool)用法的非常不可能的边缘情况,{{3}虽然这可能会被添加。

但我最大的问题是:为什么?它解决了什么问题?什么是更好来证明存在的合理性?

如果我想以有效的理由来执行,那么我个人会废除委托使用,并编写一个自定义的,特定于实现的一次性对象。代表是不必要的复杂功能。

另外:静态锁并不总是你想要的。我会把它变成一个实例,只需将该实例提供给所需的地方。但是......相同的方法可以与lock一起使用,更简单。