调用UI-Element时线程运行缓慢

Des*_*tor 3 c# wpf user-interface multithreading dispatcher

我正在编写一个基准测试工具,它从一个线程中的本地服务器读取一堆变量.

            int countReads = 1000;

            Int64 count = 0;

            for (int i = 0; i < countReads; i++)
            {
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                DateTime start = DateTime.Now;

                session.Read(null, 0, TimestampsToReturn.Neither, idCollection, out ReadResults, out diagnosticInfos);

                DateTime stop = DateTime.Now;
                Thread.CurrentThread.Priority = ThreadPriority.Normal;

                TimeSpan delay = (stop - start);

                double s = delay.TotalMilliseconds;
                count += (Int64)s;

                Dispatcher.Invoke(DispatcherPriority.Render, new Action(() =>
                {
                    progressBar1.Value = i;
                }));
            }

            double avg = (double)count / countReads;

            Dispatcher.Invoke(DispatcherPriority.Input, new Action(() =>
            {
                listBox1.Items.Add(avg);
            }));
Run Code Online (Sandbox Code Playgroud)

我正在计算进行读取和获得平均时间跨度所花费的时间跨度.

            DateTime start = DateTime.Now;

            session.Read(null, 0, TimestampsToReturn.Neither, idCollection, out ReadResults, out diagnosticInfos);

            DateTime stop = DateTime.Now
Run Code Online (Sandbox Code Playgroud)

如果我在不更新进度条的情况下运行代码,则平均花费大约5毫秒.但如果我用它来运行它

            Dispatcher.Invoke(DispatcherPriority.Render, new Action(() =>
            {
                progressBar1.Value = i;
            }));
Run Code Online (Sandbox Code Playgroud)

平均需要大约10毫秒.

我的问题是,为什么使用进度条时的时间跨度更高?我只是计算阅读的时间跨度.不包括进度条更新.

有没有办法撤离ui绘画,以免影响我的阅读时间?

谢谢你的帮助.

最好的祝福

Bri*_*eon 9

停止使用Invoke将进度信息传输到UI线程.将进度信息发布到共享数据结构或变量,并在合理的时间间隔内使用计时器对其进行UI线程轮询.我知道似乎我们都被洗脑了,认为Invoke这是做工人到UI线程交互的全部方法,但对于简单的进度信息,它可能(通常是)最糟糕的方法.

在UI线程上使用计时器的轮询方法具有以下优点.

  • 它打破了Invoke对UI和工作线程施加的紧密耦合.
  • UI线程决定何时以及多久更新一次进度信息,而不是相反.当你停下来思考它时,无论如何它应该是这样的.
  • 您可以在UI和工作线程上获得更多吞吐量.

我知道这并没有直接回答你的问题,为什么session.Read看起来运行速度较慢.尝试更改您的策略,以便将推进模型(通过Invoke)更新进度信息到拉模型(通过计时器).看看是否有所作为.即使它没有,我仍然坚持拉模型由于上面列出的原因.