【发布时间】:2020-02-21 09:37:19
【问题描述】:
我已经尝试了很多此代码的变体。无论如何,我都会收到同样的问题。 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。看看 SimpleWindow。
【问题讨论】:
-
可能发生的情况是,将文本添加到文本框并将其滚动到末尾所需的时间比更新之间的时间长,这导致一切都变得停。您可能需要不那么频繁地更新 UI。另外,不要创建数以千计的任务!这肯定会破坏一切。
-
此代码和您的 repo 中的代码未编译。您不能将 new 与方法一起使用
-
您在此处发布的代码无法编译 - 如果
SampleTask是方法,则new SampleTask(...)无法编译。 -
你能在挂起期间暂停调试器并发布调用堆栈吗?这样我们就可以知道是什么阻塞了 UI 线程。顺便说一句,
Task.WhenAll(tasks);什么都不做。 -
new SampleTask(...表示SampleTask是一个类,private void SampleTask(...表示它是一个方法。非常混乱。
标签: c# wpf multithreading