在多个线程工作时保持UI更新

时间:2017-06-06 11:08:35

标签: c# wpf multithreading

在我的窗口中,我构建了3个图表。它们不会加载特别大的数据集,但窗口加载数据需要相当长的时间。

为了解决这个问题,我对它进行了多线程处理;每组数据都是从自己的线程加载的:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    Thread BasicAlertsThread = new Thread(new ThreadStart(BuildAlertsChart));
    Thread ResolvedAlertsThread = new Thread(new ThreadStart(BuildResolvedAlertsChart));
    Thread DetailedAlertsThread = new Thread(new ThreadStart(BuildAlertDetail));

    BasicAlertsThread.Start();
    ResolvedAlertsThread.Start();
    DetailedAlertsThread.Start();
}

目前我让每个帖子在完成标签的内容时更新标签的内容,以表明已加载数据集:

lblDescription.Dispatcher.Invoke(() => { lblDescription.Content += "Basic Report Chart loaded..."; });

这里是其中一个线程正在执行的方法。每个线程都做了几乎相同的事情(与被查询的数据相关的差异)。

private void BuildResolvedAlertsChart()
{
    List<AlertsViewModel> ChartData = new List<AlertsViewModel>();
    DateTime StartingDate = DateTime.Now.AddMonths(-1);

    using (ApplicationDbContext Context = new ApplicationDbContext())
    {
        var Towers = Context.Towers.ToList();

        foreach (Tower Tower in Towers)
        {
            var AlertCount = Context.Alerts.Where(x => x.TowerId == Tower.Id && x.Date >= StartingDate && x.IsResolved == true).Count();
            if (AlertCount >= 1)
            {
                ChartData.Add(new AlertsViewModel { Alerts = AlertCount, Tower = Tower.Name });
            }
        }
    }

    this.Dispatcher.Invoke(new Action(() =>
    {
        ccResolvedAlerts.DataSource = ChartData;
        XYDiagram2D Diagram = new XYDiagram2D();
        ccResolvedAlerts.Diagram = Diagram;

        BarStackedSeries2D Series = new BarStackedSeries2D();
        Diagram.Series.Add(Series);

        Series.Brush = Brushes.ForestGreen;

        Series.DisplayName = "Resolved Alerts";
        foreach (AlertsViewModel Model in ChartData)
        {
            Series.Points.Add(new SeriesPoint(Model.Tower, Model.Alerts));
        }

        lblDescription.Dispatcher.Invoke(() => { lblDescription.Text += "Resolved Alerts Chart loaded..."; });
    }));
}

这并不是很好,但因为在更新此消息之前,UI仍然处于非活动状态。

我知道如何在单个线程工作时更新消息,但是如果所有3个线程仍然忙,我将如何进行更新?

我可以像使用单个帖子那样使用回调,但是我担心会混淆加载内容的问题以及如果我不知道什么不是使用来自3个不同线程的回调。

此外,通过这种方法,我注意到用户界面没有响应拖动或滚动等内容,直到加载了所有数据。

1 个答案:

答案 0 :(得分:-1)

也许您可以使用第四个线程来更新您的用户界面,例如this回答建议。 也可以使用BackgroundWorker来保持用户界面“活着”。