2017-12-27 37 views
-2

Dispatcher 타이머를 사용하여 UI를 업데이트하는 WPF C# 응용 프로그램이 있습니다.Dispatcher 타이머를 사용하여 WPF에서 스레드 잠금

스레드 A의 클래스 DataProcessor에서 변수 'FinalMarkers'라는 맞춤 구조체를 업데이트하고 있습니다. 스레드 실행 안에 다음

static readonly Object mLock = new Object(); 
      static List<Storage.FiducialMarkers> finalMarkers; 
      public List<Storage.FiducialMarkers> FinalMarkers 
       { 
        get { return finalMarkers; } 
        set 
        { 
         lock (mLock) 
         { 
          finalMarkers = value; 
         } 
        } 
       } 

과 : DataProcessor 내 UI의 형태로

FinalMarkers = pullFiducialData();

를, 내가 전달하고 인스턴스에

나는 다음을 사용하여 변수 업데이 트를 고정하고 Form의 생성자.

 protected DataProcessor Data = null; 

public FormView(DataProcessor _Data) 
     { 
         Data = _Data; 
      } 

내가 다음 변수를 호출하는 디스패처 타이머가 : 타이머 틱 기능에

DispatcherTimer timer = new DispatcherTimer(); 
      timer.Interval = TimeSpan.FromMilliseconds(20); 
      timer.Tick += timer_Tick3d; 
      timer.Start(); 

을, 내가 값을 잡아 :

 List<Storage.FiducialMarkers> tmpList = new List<Storage.FiducialMarkers>(); 

tmpList = Data._processingArgs.FinalMarkers; 

이 잠시 동안 실행, 오류없이 충돌합니다. 스레드 잠금을 잘못 처리하고 있습니까?

다른 스레드의 데이터를 디스패처 타이머로 전달하는 올바른 방법입니까?

감사합니다.

+0

나는 자물쇠와 관련 있다고 생각하지 않습니다. 구현 된대로 아무 것도 유용하지 않습니다. 어떤 예외가 발생했는지 파악하고 스택 추적 및 메시지를 포함해야합니다. – Evk

답변

1

getset의 자물쇠를 사용해야합니다.

public List<Storage.FiducialMarkers> FinalMarkers 
    { 
     get { 
      lock (mLock) { 
       return finalMarkers; 
      } 
     } 
     set 
     { 
      lock (mLock) 
      { 
       finalMarkers = value; 
      } 
     } 
    } 

당신이 set를 호출 할 때 잠금을 경우에, 당신은 동시에 실행되는 두 세터로부터 자신을 보호하지만 get를 호출 할 때 잠금을하지 않는 경우 다음 세트를 변조 할 수있다 비협조적인 독자가 읽는 동안 값으로 이것은 작가가 자물쇠를 잡고 있는지 여부에 관계없이 발생합니다. 잠금은 여러 스레드 간의 계약입니다. 하나의 스레드 (작성자)만이 계약에 바인딩되어 있다면 다른 스레드 (독자)는 부적절한 순간에 읽기를 수행하고 잠재적으로 일종의 충돌이나 손상을 일으킬 수 있습니다.

자물쇠는 "이 코드 블록을 동시에 사용하지 않겠습니다"라고 말합니다. 잠금 블록 안에 finalMarkers에 액세스하는 데 관련된 코드를 넣으면 모든 스레드가 동의해야합니다.

FYI : 구조체 자체에 값 의미론이 있으므로 get을 수행 할 때 복사됩니다.

+0

감사합니다! 이것은 더 오랫동안 실행되지만, 다음 처리 중입니다 : 처리되지 않은 예외 : System.NullReferenceException : 객체 참조가 객체의 인스턴스로 설정되지 않았습니다. FormView.timer_Tick3d (Object sender, EventArgs e)의 '스레드 안전 문제 일 가능성이 있습니까? 아니면 다른 것을 놓칠 수 있습니까? – anti

+1

@anti이 변경 사항을 적용하지 않은 경우와 완전히 동일한 문제가 발생합니다. 동시에 여러 스레드에서 동일한 목록에 액세스하고 있으며이를 수행 할 수 없습니다. – Servy

+0

고맙습니다. 이와 같은 문제를 해결하기 위해 받아 들여지는 방법은 무엇입니까? 읽기/쓰기 잠금이 실행하지 않습니까? – anti