内置进度报告程序允许更新UI元素,同时还可以在线程池上运行(参考here)。对于偶尔更新UI元素而言,这是完美的选择,我发现的所有示例都展示了这种情况。
但是,我需要在CPU绑定工作运行时不断更新WPF UI元素,以便它以这种方式在消息中“循环”直到工作完成:
跑步
跑步。
跑步..
跑步...
正在运行
这如何在不阻塞UI线程的情况下完成?
这是当前的实现:
internal async Task<bool> FireWithStatusAndWork(IProgress<string> progress) {
var reportedProgress = "Running";
bool continueReporting = true;
bool workStarted = false;
// loop through the message, but also do background work
while (continueReporting) {
if (!workStarted) {
workStarted = true;
await Task.Run(() => { model.CPUIntensiveWork(); }).ConfigureAwait(false);
continueReporting = false;
}
progress.Report(reportedProgress);
if (reportedProgress.Length < 10) reportedProgress += "."; else reportedProgress = "Running";
Thread.Sleep(200);
}
return true;
}
对于另一个异步新手问题,我深表歉意,但我试图从哲学的角度(正确使用某些场景,而不是其他场景)和实践角度(只是让事情运行)来学习。 / p>
我已经浏览了MS docs for TAP ...,但是如果我错过了相关的内容,请将其作为学习重点,将不胜感激。
答案 0 :(得分:2)
假设您await
正在Task
,那么您的循环将只运行一次。您应该创建任务并定期检查其状态,而不是等待任务立即完成。
类似的事情应该起作用:
internal async Task<bool> FireWithStatusAndWork(IProgress<string> progress)
{
var reportedProgress = "Running";
var task = Task.Run(() => model.CPUIntensiveWork());
while (!task.IsCompleted)
{
progress.Report(reportedProgress);
if (reportedProgress.Length < 10)
{
reportedProgress += ".";
}
else
{
reportedProgress = "Running";
}
await Task.Delay(200);
}
return true;
}