使用Dispatcher Timer在WPF中进行线程锁定

问题描述 投票:-2回答:1

我有一个WPF C#应用程序,它使用Dispatcher Timers来更新UI。

在线程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的实例传递给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;

这将运行一段时间,然后崩溃而不会出错。我处理线程锁错了吗?

这是将数据从另一个线程传递到调度程序计时器的正确方法吗?

谢谢。

c# wpf multithreading
1个回答
1
投票

你需要锁定get以及set

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

如果你在调用set时拿锁,那么你可以保护自己免受同时运行的两个setter,但是如果你在调用get时没有锁定,那么该组可能会在它被篡改时篡改由不协调的读者阅读;无论作者是否持有锁,都会发生这种情况。锁是多个线程之间的协议。如果只有一个线程(编写器)绑定到协议,那么另一个线程(读取器)将在不合时宜的时刻执行其读取,并可能导致某种冲突或损坏。

锁说“让我们不要同时执行这段代码”。您必须通过在锁定块中访问访问finalMarkers所涉及的任何代码来获得所有线程的同意。

仅供参考:结构本身具有值语义,因此在执行get时会复制它。

© www.soinside.com 2019 - 2024. All rights reserved.