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

标签 c# wpf multithreading user-interface 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);
            }));

我正在计算继续读取所需的时间跨度,并在最后获得平均时间跨度。

            DateTime start = DateTime.Now;

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

            DateTime stop = DateTime.Now

如果我在不更新进度条的情况下运行代码,平均需要大约 5 毫秒。 但如果我用

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

平均大约需要 10 毫秒。

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

有什么方法可以撤离 ui-painting 使其不影响我的阅读时间跨度吗?

感谢您的帮助。

最好的问候

最佳答案

停止使用 Invoke 将进度信息传输到 UI 线程。将进度信息发布到共享数据结构或变量,并让 UI 线程在合理的时间间隔内使用计时器对其进行轮询。我知道似乎我们都被洗脑了,认为 Invoke 是执行 worker-to-UI 线程交互的最重要方法,但对于简单的进度信息,它可以(而且经常是)最糟糕的方法。

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

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

我知道这并不能直接回答您关于为什么 session.Read 运行速度变慢的问题。尝试将更新进度信息的策略从推送模型(通过 Invoke)更改为拉模型(通过计时器)。看看这是否有所作为。即使不是这样,出于上述原因,我仍然会坚持使用拉式模型。

关于c# - 调用 UI-Element 时线程运行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10211096/

相关文章:

c# - 业务对象是否应该具有行为?

c# - 为什么使用 .AsEnumerable() 而不是强制转换为 IEnumerable<T>?

multithreading - 检测您何时进入/离开 Xamarin.iOS 中的主线程

python - 当我在 Python 中使用多线程时无法获得结果

c# - 在 C# 中打开具有完全访问权限的 Excel 工作表

c# - SC 删除 <服务> 不起作用

c# - 如何知道文本是否大于文本框?

c# - DataGrid mvvm/wpf 内的 ComboBox 上的 SelectionChanged 的​​ EventToCommand

c# - 用户控件中的图像未显示在窗口中

java - 线程 :Wait() and notify()