【问题标题】:Multithreaded, Multi-Dispatcher WPF app still draws in a single thread?多线程、Multi-Dispatcher WPF 应用程序仍然在单线程中绘制?
【发布时间】:2011-12-17 20:22:03
【问题描述】:

我有一个 WPF 和 C# 应用程序,其中包含一个大约 35 列 x 50 行的大型 DataGrid,用于监视一组经常变化的值。问题是,当整个网格可见时,刷新它会使用户界面挂起几乎一秒钟。我每两秒显式刷新一次,这对我正在做的事情来说很好,但是让 UI 的其余部分挂起真的很痛苦。

好的,所以我决定在一个单独的窗口中使用单独的 Dispatcher 在单独的线程中运行 UI 的其余部分。我编写了一个玩具窗口,其中仅包含一个 textBlock,其递增计数使用 DispatcherTimer 每秒更新 10 次。然而,计数并没有平滑地增加,而是在网格刷新时暂停,然后继续显示计数比暂停时高出大约 10,因此正在处理计时器事件。我只是没有看到刷新。

WPF 是否只在一个线程中绘制其所有元素?有什么办法吗?

这是我的第二个窗口创建代码:

private void Window_Loaded( object sender, RoutedEventArgs e )
{
    ThreadStart ts = new ThreadStart( RunSpareThread );
    m_spare_thread = new Thread( ts );
    m_spare_thread.IsBackground = true;
    m_spare_thread.Priority = ThreadPriority.Highest;
    m_spare_thread.SetApartmentState( ApartmentState.STA );
    m_spare_thread.Start();

    Dispatcher.Thread.Priority = ThreadPriority.Lowest;
}

void RunSpareThread()
{
    m_spare_window = new SpareWindow();
    m_spare_window.Show();
    Dispatcher.Run();
}

仅供参考,我尝试了几种不同的方式来实现网格 - 作为 ListView,作为覆盖 OnRender 并绘制一大堆 GlyphRunDrawings 的 Canvas - WPF 绘制这些东西的速度非常慢。

【问题讨论】:

    标签: c# wpf multithreading performance


    【解决方案1】:

    很遗憾,是的。也就是说,您可以做很多事情来提高 ui 的响应能力。主要的事情之一是确保在 UI 线程中完成的工作量最少。这意味着在单独的上下文中进行所有数据库读取等。你还应该看看你的网格是如何显示你的值的——它是虚拟化的吗?然后还有数据绑定的方式,绑定源应该只允许您在所有更改完成后更新绑定。

    【讨论】:

      【解决方案2】:

      如果使用得当,WPF 会非常快。

      一些提示:

      1. 实现您要显示的数据的模型(或视图模型MVVM)。确保它实现了INotifyPropertyChanged 接口。将此类模型的集合绑定到您的DataGrid
      2. 不要每 N 秒刷新一次所有数据。您应该以某种方式检测数据更改(使用工作线程)并更新适当模型上的适当属性。由于数据绑定,所有更改都会自动反映在 DataGrid 上。所以,你甚至不需要使用Dispatcher(至少是明确的);
      3. 如果您不需要对数据执行特殊操作(如编辑、排序、过滤等),请使用 ListView 而不是 DataGrid
      4. 如果您需要显示大量行,请考虑实现 virtualization

      【讨论】:

        猜你喜欢
        • 2023-03-05
        • 2019-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多