0
在我的窗口中,我構建了3個圖表。他們沒有加載特別大的數據集,但窗口加載數據需要相當長的時間。在多線程工作時保持UI更新
爲了解決這個問題,我對它進行了多線程處理;每一組數據正在從它自己的線程加載:
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個不同線程的回調函數,哪些不是。
此外,使用這種方法,我注意到用戶界面沒有響應像拖動或滾動,直到所有的數據加載。
它確實取決於非UI線程的功能。他們是否訪問UI線程?他們是否填寫了一個綁定的集合(並因此將事件提交給UI)等。 –
基本上他們只是收集信息並在圖表中顯示。我已經更新了這個問題來展示一個例子。 – Ortund
那麼,工作線程的示例代碼會做兩件事情 - 第一個塊從數據庫中檢索數據並在工作線程上運行。然而,將數據綁定到圖表的第二部分(Invoke內的整個塊)正在UI線程上執行,並且如果速度很慢......很快,看起來大部分代碼正在UI線程上同步執行,這解釋了無反應性。 –