0

私は、すべてのDBロジック(読み取りと書き込み)が次のように囲まれているプロジェクトに取り組んでいます。

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 */ }れますか?

4

1 に答える 1

1

まあ、それは維持するための余分なコードであり、GCが処理するための多くの余分なオブジェクト(それらのほとんどはgen-0で死ぬので、おそらく重要ではありません)、そしてたくさんの余分なロックハンドル(これはdisposeInterlockedでaの代わりに使用)。lock(this)

また、ここで説明する現在のコンパイラでの使用法の導入を引き起こした非常にありそうもないエッジケースを完全には処理しませんが、おそらく追加される可能性があります。Monitor.Enter(object, ref bool)

しかし、私の最大の質問は、なぜですか?それはどのような問題を解決していますか?存在を正当化することは何をより良くしているのでしょうか?

正当な理由でそれを実行したい場合は、個人的にデリゲートの使用を廃止し、カスタムの実装固有の使い捨てオブジェクトを作成します。デリゲートは不必要な複雑さです。

また、静的ロックは必ずしも必要なものではありません。私はそれをインスタンスにし、そのインスタンスを必要な場所で利用できるようにします。ただし...同じアプローチをlock、はるかに簡単に使用できます。

于 2012-07-06T06:19:08.033 に答える