2017-12-27 473 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