[英]Running multiple background tasks in a WPF applicatiion - UI update stalling
我已經嘗試了這段代碼的很多變體。 無論如何,我都收到了同樣的問題。 UI 更新開始正常,然后停止,直到整個過程完成。 有人可以指出我正確的方向嗎?
場景
在 WPF 應用程序中,我們將使用不同的參數調用相同的 API 數千次。 我們需要收集所有的回應並做一些事情。
示例代碼
List<Task> tasks = new List<Task>();
for (int i = 1; i <= iterations; i++)
{
Task t = SampleTask(new SampleTaskParameterCollection { TaskId = i, Locker = locker, MinSleep = minSleep, MaxSleep = maxSleep });
tasks.Add(t);
}
Task.WhenAll(tasks);
private void SampleTask(SampleTaskParameterCollection parameters)
{
int sleepTime = rnd.Next(parameters.MinSleep, parameters.MaxSleep);
Thread.Sleep(sleepTime);
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
lock (parameters.Locker)
{
ProgressBar1.Value = ProgressBar1.Value + 1;
LogTextbox.Text = LogTextbox.Text + Environment.NewLine + "Task " + parameters.TaskId + " slept for " + sleepTime + "ms and has now completed.";
}
LogTextbox.ScrollToEnd();
if (ProgressBar1.Maximum == ProgressBar1.Value)
{
RunSlowButton.IsEnabled = true;
RunFastButton.IsEnabled = true;
ProgressBar1.Value = 0;
}
}), System.Windows.Threading.DispatcherPriority.Send);
}
當前存儲庫位於GitHub 上。 看看簡單窗口。
不要創建數以千計的任務——這會導致巨大的性能問題。
相反,使用Parallel.For()
類的東西來限制同時運行的任務數量; 例如:
Parallel.For(1,
iterations + 1,
(index) =>
{
SampleTask(new SampleTaskParameterCollection { TaskId = index, Locker = locker, MinSleep = minSleep, MaxSleep = maxSleep });
});
此外,如果 UI 更新花費的時間比調用BeginInvoke()
的時間間隔長,那么調用將開始排隊,事情會變得很糟糕。
為了解決這個問題,您可以在 SampleTask() 中使用一個計數器,每 N 次調用才實際更新一次 UI(使用合適的 N 值)。
但是,請注意,為避免線程問題,您必須在遞增和檢查計數器值時使用Interlocked.Increment()
(或其他一些鎖)。 您還必須確保在所有工作完成后最后一次更新 UI。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.