2011-10-24 9 views
1

1)私はプロジェクトで作業していますが、このコードを見ましたが、Monitor.Lockステートメントのポイントは何か分かりません。誰かがしようとしていることを説明することはできますか?BeginUpdateとEndUpdateの実装

2)パラメータ名のポストスクリプトのアンダースキャンは実際には迷惑ですが、誰もこの命名規則を見ていますか?

public class FieldsChangeableHelper<T> : IFieldsChangeable<T> 
{ 
    object _lock; 
    int _lockCount; 
    FieldChanges<T> _changes; 

    public FieldsChangeableHelper() 
    { 
     _lock = new object(); 
     _lockCount = 0; 
    } 

    public void AddChange(T field_, object oldValue_) 
    { 
     if (_changes == null) 
      _changes = new FieldChanges<T>(field_, oldValue_); 
     else 
      _changes.AddChange(field_, oldValue_); 
     if (RaiseEvent(_changes)) 
      _changes = null; 
    } 

    #region IFieldsChangeable Members 

    public void BeginUpdate() 
    { 
     if (System.Threading.Interlocked.Increment(ref _lockCount) == 1) 
      Monitor.Enter(_lock); 
    } 

    public void EndUpdate() 
    { 
     if (System.Threading.Interlocked.Decrement(ref _lockCount) == 0) 
     { 
      FieldChanges<T> changes = _changes; 
      _changes = null; 
      Monitor.Exit(_lock); 
      RaiseEvent(changes); 
     } 
    } 


    protected bool RaiseEvent(FieldChanges<T> changes_) 
    { 
     if (_lockCount == 0 && Changed != null && changes_ != null) 
     { 
      Changed(this, changes_); 
      return true; 
     } 
     return false; 
    } 

    public event FieldsChanged<T> Changed; 

    #endregion 
} 

答えて

0

Monitor.Lockは、複数のスレッドが同じ部分を並行して実行しようとするとコードの一部をロックします。 1人の人間だけがコンテキストを変更/実行していることを保証するために作られています。 MSDNを見てください。

ロックオブジェクトは常に静的ですが、あなたの場合はそうではありません。開いているタイプのインスタンス化する複数のオブジェクトの場合は、いくつかの問題が発生する可能性があります。 CSHARPでなど

オープンT上の静的ジェネリックで注意一つのことは、つまり、あなたの場合はオープンタイプのクラスの静的メンバは、Tすなわち日時、文字列のために異なっている、異なるタイプのために異なっている、

、プライベート型のメンバは、通常、プレフィックス_

0

と私はそれを読む方法を命名されていますBeginUpdateメソッド()現在のスレッドの呼び出しは、インスタンスへの排他的アクセスを持っていることを保証し、EndUpdateのが呼ばれたら、その変更イベントが実質的にバッチ処理と発生します。作者は、同じスレッドでBeginUpdate()を何度も呼び出すなどの再帰処理を行い、ロックが解除されるまでUpdateEventsをバッチする仕組みにしたいと考えました。なぜなら、まだ自分自身にロックしているときにイベントを発生させると、デッドロックが発生する可能性があるからです。イベント・サブスクライバーはメンバーにアクセスしたいので、すでにロックされている送信側インスタンスをロックする必要があります。

Monitorクラスに基づくロックが再帰的でカウントされるので、条件付きロックは必要ありません(私の分析が正しい場合)。

ロック機構にはもう1つの問題があります。つまり、現在1つのスレッドがロックを保持しているときです。 2番目のスレッドはロックを待つこともなくなりますが、ロックは条件付きであるため、ロックなしで続行されます。これは大きなバグのようです!

命名規則について。私はパラメータと地元の人と私物を区別する方法のためにそれを自分で使います。多くのC#コーディング規約で推奨されています。

void Method(int number) 
{ 
    // no need to refer to this since: 
    //this.number = number; 
    // can be replaced with 
    _number = number; 
} 
+0

しかし、唯一の最初のスレッドがその System.Threading.Interlocked増加の背後にあるので、Monitor.Lockを呼び出します。これは、このような場合に役立ちますか? – Ant

+0

@Ant - 私の答えは更新されました。これはバグであり、あなたが本当に何をやっているのか分からない限り、同期に関しては手動ではあまりやらなければならない良い理由です – Polity

関連する問題