2017-12-27 474 views
-2

我有一個WPF C#應用程序,它使用分派器計時器來更新UI。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; 
         } 
        } 
       } 

,然後線程運行中:

FinalMarkers = pullFiducialData();

在我的UI形式,我傳遞的DataProcessor到實例

我使用下面的鎖定變量更新表單的構造函數。

 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

您需要取鎖get以及set

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

如果您在呼籲set採取鎖,然後你保護自己在同一時間運行兩個setter方法,但是如果當你調用get你不採取鎖則可以集合篡改與不協調的讀者閱讀時的價值;無論作者是否持有鎖,這都會發生。該鎖是多個線程之間的協議。如果只有一個線程(作者)被綁定到協議上,那麼另一個線程(讀者)將在不合時宜的時刻結束執行讀取操作,並可能導致某種衝突或損壞。

鎖說:「我們不要同時做這個代碼塊」。你必須讓所有線程都同意通過將任何代碼放入鎖塊中訪問finalMarkers

僅供參考:結構本身具有值語義,因此它在執行get操作時被複制。

+0

謝謝!這會運行更長的時間,但後來我得到:'未處理的異常:System.NullReferenceException:未將對象引用設置爲對象的實例。 at FormView.timer_Tick3d(Object sender,EventArgs e)'這可能也是一個線程安全問題,或者我可能錯過了其他的東西? – anti

+1

@anti你有沒有這個變化的問題完全一樣。您仍然同時訪問多個線程中的同一列表,而且您無法做到這一點。 – Servy

+0

謝謝。解決這個問題的可接受方式是什麼?讀/寫鎖會不會這樣做? – anti