Reputation: 1
The following code abstracts away my actual task, which is to go through each pixel in a bitmap.
myButtonCommand.execute(async () => {
await Task.Run(() => {
while(i++<1000000) {
// do some work
if(i % 1000 == 0) // only update on every 1000th iteration
{
ProgressChanged.Invoke(this, i); // fire update event
Thread.Sleep(n);
}
}
});
});
The lambda that is supplied to myButtomCommand.execute
runs on the UI thread. But since Tasks aren't guaranteed to run on the UI thread doesn't that mean that calling Thread.Sleep(n)
could possibly freeze the UI thread?
The underlying problem is that I need to update a progress bar and without doing a Thread.Sleep(n)
the UI thread gets blocked while the Task is spinning.
Now, what I ended up doing was using Thread.Sleep(0)
so it will only go to sleep if another thread needs to run. But I don't understand why using Thread.Sleep(n)
is necessary in the first place since, at least in my tests, it was on a separate thread anyways.
So I'm confused about two things:
Thread.Sleep(n)
from a Task off the UI thread?Thread.Sleep(n)
necessary to get the UI to update given the Task ran on a separate thread?Upvotes: 1
Views: 118
Reputation: 3037
and without doing a Thread.Sleep(n) the UI thread gets blocked while the Task is spinning.
That means you were just calling too many Invokes here.
The GUI thread was not 'blocked', just overworked.
Another, and probably better approach
//if(i % 1000 == 0)
if(i % 1000000 == 0)
Upvotes: 1
Reputation: 45096
Similar and I can assure you the UI does not freeze.
Look up progress on async.
await Task.Delay(500);
may be all you need.
async Task<int> TaskDelayAsync(CancellationToken ct, IProgress<int> progress)
{
int i = 0;
while (true)
{
i++;
//Debug.WriteLine(i);
progress.Report(i);
ct.ThrowIfCancellationRequested();
await Task.Delay(500);
}
return i;
}
Upvotes: 1