2011-10-03 4 views
0

일부 사용자 지정 개체를 표시하기위한 컨트롤이있는 양식이 있습니다. 나는 그들이 서버에서 들어올 때 ToAdd List에 객체를 추가하는 AddObject 이벤트를 구독한다. 타이머를 설정하여 ToAdd List에서 Display List로 개체를 복사 할 때마다 10 초마다 실행하도록 타이머를 설정했습니다.이 목록에 바인딩 된 개체는 한 번에 하나씩 컨트롤에 대량으로 항목을 추가하는 것이 더 효율적이었습니다. 컨트롤을 선택하면 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에서 동일한 동기화 개체를 사용하고 있습니다. 서로 차단되지 않도록 서로 다른 두 개의 동기화 개체를 사용하십시오. –

+0

@UnmeshKondolikar, 그들은 * Display * 목록을 보호하기 때문에 서로를 차단해야합니다. –

답변

1

예. 안전합니다. 기술적으로 잠김은 BeginInvoke에 없지만 delegate에서 생성 된 익명의 기능입니다.

일부 노트 :

  • List<T> 여러 Add보다 효율적 인 AddRange 방법이있다.
    처럼 사용 Display.AddRange(ToAdd);
  • IntermittentProcessMessages의 대리인은 BeginInvoke이 즉시 반환하므로 try-catch가 적용되지 않습니다.
관련 문제