Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Threading Model and Application.DoEvents vs. Thread.Sleep

We have a desktop application that performs a pretty rigorous set of calculations in a background thread. Portions of this calculation are performed in an unmanaged library that we access through interop. What we are finding is that, when we kick off the calculation, the UI thread becomes unresponsive for the duration of the calculation. We were under the impression that the framework would handle the thread switching to permit the UI to continue to be responsive, but that is not the case. We have found that we can insert a Thread.Sleep(0) or Application.DoEvents() to permit the UI to be responsive. This has the side effect of slowing the calculation. Also, portions of the calculation performed by the unmanaged code can take up to 30 seconds to complete, and during this time the application is always unresponsive. The entire calculation can take anywhere from two to five minutes to complete.

This leads to the following questions:

  • What is the .NET framework threading model with regard to the UI and interop?
  • Are we incorrect in assuming that the framework should handle thread switching between the background and UI threads?
  • What is the difference between using Thread.Sleep and Application.DoEvents in this situation, and is one preferred over the other?
like image 783
JadeMason Avatar asked Apr 28 '09 15:04

JadeMason


People also ask

What is application DoEvents ()?

Application. DoEvents() can be used to process the messages waiting in the queue on the UI thread when performing a long-running task in the UI thread. This has the benefit of making the UI seem more responsive and not "locked up" while a long task is running.

Does thread sleep block other threads?

Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution. One thread cannot call Thread. Sleep on another thread.

Is thread sleep asynchronous?

The amazing thing is that the Thread. sleep will not block anymore! It's fully async.

Does thread Sleep cause context switch?

Every time we deliberately change a thread's status or attributes (e.g. by sleeping, waiting on an object, changing the thread's priority etc), we will cause a context switch.


2 Answers

You could lower the priority of your background thread, so it will be preempted more by the OS. If you have some domain knowledge that leads you to want to control when it's preempted, you could go with Thread.Sleep(0) which surrender your timeslice if there's another thread waiting.

Application.DoEvents pumps the windows message queue. This will cause your app to respond to events like keystrokes or window resizes. Thread.Sleep will cause your thread to be preempted (or maybe not, in the case of Thread.Sleep(0)).

Also read Threading in C#

like image 106
aumfer Avatar answered Oct 25 '22 14:10

aumfer


Your best bet is by creating your own Thread. DoEvents and Thread.Sleep(0) blocks the calculation, slowing it down. You can wrap your DLL calls in either a ThreadStart delegate or a ParameterizedThreadStart delegate and use the delegate name as a parameter when you instantiate the Thread. From there, all you have to do is call the Thread's Start method.

like image 25
Bob Avatar answered Oct 25 '22 15:10

Bob