Reputation: 5281
The built-in progress reporter allows for a UI element to be updated, while also running on the thread pool (ref here). This is perfect for occasional updates to a UI element, and all examples I've found showcase that scenario.
However, I need to continuously update a WPF UI element while the CPU-bound work is running, so that it 'loops' through a message in this way until the work is finished:
Running
Running.
Running..
Running...
Running
How can this be accomplished without blocking the UI thread?
Here's the current implementation:
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;
}
I apologize for yet another async newbie question, but I'm trying to learn from both a philosophical standpoint (proper use for some scenarios but not for others) as well as a practical one (just get the thing running).
I have looked through MS docs for TAP... but if I've missed something pertinent I would be grateful if that were provided as a learning point.
Upvotes: 0
Views: 1167
Reputation: 32058
Your loop will only ever run once, given that you are await
ing the Task
. Rather than waiting for the task to complete at once, you should create the task and check for its status periodically.
Something like this should work:
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;
}
Upvotes: 2