1

Is there a harm in using Thread.Sleep(0) in a BackgroundWorker thread? Is there a benefit?

I use BackgroundWorker for things like lengthy database queries, datatable builds, https web queries, etc. These tasks sometimes take up to five seconds to complete. I thought I observed BackgroundWorker making the UI slightly less responsive, but I may be mistaken. So, I placed Thread.Sleep(0) in the BackgroundWorker code. Did that actually help me? Did it hurt me?

EDIT: I am trying to make the UI thread more responsive. I believed that Sleep(0) would yield time to the UI thread during tight loops, and make the UI more responsive, but maybe I'm wrong. I don't care how long the background task takes.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Ray White
  • 297
  • 4
  • 19
  • 8
    You might consider switching to [async](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) – Klaus Gütter Nov 03 '21 at 17:57
  • If anything it should have decreased performance. Sleep(0) is not feasible, it will only consume CPU time. – Stefan Nov 03 '21 at 18:01
  • 3
    @Stefan, I think that the OP is not concerned about the performance of the thread that calls `Sleep(0)`. OP is asking whether it will improve the performance of _other_ threads. [Documentation for the Thread class](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread?view=net-5.0) suggests that `Sleep(0)` is equivalent to `Yield()`, so the question is equivalent to asking whether `Thread.Yield()` will improve the performance of other threads. – Solomon Slow Nov 03 '21 at 18:09
  • It runs on the same CPU right? Unlikely, but possibly even the same core. I am trying to point out its mainly a wast of resources. In addition, if you require such measures its a sign something fishy is going on. I would suggest to follow Klaus's suggestion. – Stefan Nov 03 '21 at 18:16
  • I am trying to make the UI thread more responsive. I believed that Sleep(0) would yield time to the UI thread and make it more responsive, but maybe I'm wrong. – Ray White Nov 03 '21 at 18:20
  • "The number of milliseconds for which the thread is suspended. If the value of the millisecondsTimeout argument is zero, the thread relinquishes the remainder of its time slice to any thread of equal priority that is ready to run. If there are no other threads of equal priority that are ready to run, execution of the current thread is not suspended." - https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.sleep?view=net-5.0 OK, that's for net 5 but it's the same for others. What's your priority? UI responsiveness? Getting all jobs done asap? – Adam Benson Nov 04 '21 at 10:50

1 Answers1

1

A benefit? No, it is just a stab for a stop on 0 milliseconds. Maybe, it is useful to dynamically change the delay. But I don't know a useful case for it.

Harm? Not big, just a few OS instructions to make the stop and keep it on. No result but some additional work.

BackgroundWorker by its definition is for heavy/long tasks that shouldn't block UI (block elements, fill your form with a single color, ...). That

slightly less responsive

behavior comes from the heavy task in the background. Your machine still has the same OS/RAM/CPU that should be shared between all of your threads and tasks. If your machine is out of free resources then existing ones will be shared in time. Kind of an additional big player that pushes existing ones.

Update. As properly noticed Solomon Slow, Sleep(0) is an equivalent for Yeld() (pass execution to another thread that is ready to run on the current processor). So it COULD slow your BG process, make it work longer.

Update on EDIT. Having the background process (another thread) already unblocked your UI. To separate these threads even more - you can try a Thread's Priority property: https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.priority .

For example, assign a ThreadPriority.BelowNormal value at your back ground thread while your main thread will have it ThreadPriority.Normal. Btw, BackgroundWorker has no such field or control. It has the same priority as your UI one. If you'll need such priority control - replace it with new Thread(...). The change will drop BackgroundWorker's implemented result processing events such as ProgressChanged, RunWorkerCompleted. If you use them then you can implement firing similar events from your Thread on your own.

PIoneer_2
  • 470
  • 4
  • 12