views:

312

answers:

4

I've written a .NET winforms application that uses a secondary thread to do some heavy processing, which communicates it's progress back to the UI thread. Everything works correctly, the form shows the progress, and I've also created a cancel button to interrupt the processing thread. However, when the time consuming process is going the application and my entire computer slows way down. It takes a long time drag windows around, and there is even a significant delay when trying to type letters into notepad.

I'm assuming I need to reduce the priority of the processing thread, and/or increase the priority of the UI thread. Is this right? Right now both threads are Normal priority.

Is it just as easy as the follwing? Or is there something else I should do?

Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

How should I change the priorities? Should I reduce the priority of the processing, or increase the priority of the UI, or both? And to what setting? AboveNormal, or highest?

A: 

You generally want to leave the priority of your main thread alone, and reduce the priority of the processing thread to Idle.

Jerry Coffin
Setting it to idle will make a long running, computationally intensive routine take a LOT longer, potentially. Better to set it to BelowNormal.
Reed Copsey
@Reed:There won't typically be any difference between the two at all. The only way there's any difference is if there's another thread at Idle or BelowNormal priority -- neither of which is particularly common.
Jerry Coffin
There are quite a few services set at BelowNormal. I've actually found a noticeable difference in my code...
Reed Copsey
@Reed:That sounds suspect to me -- in the whole time since Windows NT 3.1, I've yet to see a single service set to run at BelowNormal priority. Even if such a thing did exist, it would only make a difference if the service was ready to run -- and when that happens, it (normally) means it's been invoked by an active process, in which case you *want* it to take priority over your background thread.
Jerry Coffin
+1  A: 

If you want the background thread to not effect the system responsiveness as a whole, you'll need to lower it's priority, most likely by setting it's Priority to BelowNormal.

Otherwise, it will have the same effect you're currently seeing.

That being said, I'd be hesitant to do this in my own code. If your program is run on a system with more processing cores, this will likely not be an issue, and lowering the thread priority (potentially) will cause your algorithm to take longer to process.

Reed Copsey
+3  A: 

I dont necessarily think thread priority is your issue (though it could be part of it). Take a look at this SO question: Background Worker Thread Priority.

It is probably overly tight loops in your background thread which are keeping cpu time on that thread. There are several ways to fix it from the brutal (thread sleeps) to the more reasonable (mutexs and events).

You can also try profiling the background thread (either directly, or in a test harness) to see where it is spending the majority of its time, and try to isolate this with async events or similar offloading techniques.

GrayWizardx
+1 - this is the best solution
Tim
If the work is truly "heavy processing", as specified, then trying to use mutexes and events, etc, will just dramatically slow down the processing. Using your CPU to its fullest is not a bad thing - using it unnecessarily is the problem...
Reed Copsey
It depends on the definition of "heavy processing". I agree with you though Reed, if you are already tightly invested then adding additional context switches is just going to make it worse. It has been my experience though, that sometimes carefully applied segmentation of work (using mutexes and signals) can alleviate processor contention, without significantly impacting speed, though there will always be some loss.
GrayWizardx
A: 

Normally you should set the priority of the worker thread to a nice level (eg the user might want to do someing in another application and even them the worker thread should play nice) even though Windows already boosts the "active" processes thread (the application you have a window with input focus) a little bit so it will feel more responsive. The higher priorities are usually needed when you need to meet some time constraints.

Ritsaert Hornstra
Also one note (not the main issue): you should be aware that having threads with different priorities may yield strange concurrency issues (things like: what if a thread with a lower prio grabs a critical section and is never scheduled again because a normal or higher prio thread takes the whole CPU)
Ritsaert Hornstra
@Ritsaert:The Windows scheduler has "starvation prevention", so even if something is set to low priority, its priority will occasionally get "bumped" so it gets to run and (eventually) release the critical section/mutex/whatever it's holding.
Jerry Coffin
@Jerry: Thanks for the addition. I know newer Windows versions have that but even with that in place it can hold locks for a long time (relatively speaking)
Ritsaert Hornstra
@Ritsaert:It's no longer just "newer" Windows versions -- IIRC, it was introduced around the NT 4.0 time frame.
Jerry Coffin
@Jerry: You might be right: I tried to Google it and it looks like it is added since Window 2000. And I cannot call that a very recent version can I. I did however find the following article interesting (see the comments also): http://www.codinghorror.com/blog/archives/000671.html
Ritsaert Hornstra
@Ritsaert:Interesting article, but it's pointing the blame in the wrong direction. If you look carefully, he mentions a processing sleeping -- and that's the real source of the problem. Thread synch should be done with things like WaitForSingleObject, not with sleep. If changing priorities changes overall behavior, chances are your code is wrong, and only getting by because the scheduler has lots of band-aids to cover for it (but it can only use most of them for normal/dynamic priority threads).
Jerry Coffin
@Ritsaert:Doing a bit of looking at the comments on that article, I notice a few other people made roughly the same point I was trying to.
Jerry Coffin
@Jerry: Exactly, the comments we're especially valuable. Let's leave it at that!
Ritsaert Hornstra