2011-10-03 6 views
0

私はいくつかのカスタムオブジェクトを表示するためのコントロールを持つフォームを持っています。フォームの中で私はToAdd Listにオブジェクトを追加するイベントAddObjectを購読します。私は、ToAdd ListからDisplay Listにオブジェクトをコピーするために10秒ごとに実行するタイマーをセットアップしました。(これは、アイテムが入ったときに一度に1つ以上のコントロールに一括して項目を追加する方が効率的でした。私のフォームのコントロール、ToAdd Listをクリアします。 BeginInvokeの内部にロックを入れても安全ですか?これを行うより良い方法はありますか?BeginInvokeコールの内部にlock()を置いても安全ですか?

 private System.Threading.Timer aTimer; 
     private readonly Object sync = new Object(); 
     List<object> ToAdd = new List<object(); 
     List<object> Display = new List<object(); 

     private void Init() 
     { 
      TimerCallback tcb = IntermittentProcessMessages; 
      aTimer = new System.Threading.Timer(tcb, null, 1000, 100); 
      Server.MessageReceived += AddObject; 
     } 

     private void AddObject(object t) 
     { 
      lock (sync) 
      { 
       try 
       { 
        ToAdd.Add(t); 
       } 
       finally() {} 
      } 
     } 


     private void IntermittentProcessMessages(object source) 
     { 
      try 
      { 
       if (this.IsHandleCreated == false) 
       { 
        return; 
       } 
       this.BeginInvoke((Action)delegate() 
       { 
        lock (sync) 
        { 
         if (ToAdd.Count > 0) 
         { 
          ToAdd.ForEach(f => Display.Add(f)); 
          ToAdd.Clear(); 
         } 
        } 
       } 
      } 
      finally(){} 
    } 
+0

私にはうまく見えます。 – Gabe

+0

AddObjectとBeginInvokeで同じ同期オブジェクトを使用しています。 2つの異なる同期オブジェクトを使用して、相互にブロックされないようにします。 –

+0

@UnmeshKondolikar、彼らは 'Display'リストを保護するので、彼らはお互いをブロックすべきです。 –

答えて

1

はい、安全です。技術的には、ロックはBeginInvokeにありませんが、delegateから作成された無名関数にあります。

いくつかの注意:

  • List<T>は、複数のAddよりも効率的であるAddRange方法があります。
    likeそれを使用Display.AddRange(ToAdd);
  • IntermittentProcessMessagesのデリゲートは、すぐにBeginInvokeが返されるため、try-catchによってカバーされません。
関連する問題