簡體   English   中英

在 WPF 應用程序中運行多個后台任務 - UI 更新停滯

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM