user875234
user875234

Reputation: 1

Can calling Thread.Sleep(n) from a Task off the UI thread freeze the UI?

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:

  1. Is it safe to call Thread.Sleep(n) from a Task off the UI thread?
  2. In my example, why is Thread.Sleep(n) necessary to get the UI to update given the Task ran on a separate thread?

Upvotes: 1

Views: 118

Answers (2)

bommelding
bommelding

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

paparazzo
paparazzo

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

Related Questions