Solved

BackgroundWorker thread completion and GUI thread interaction

Posted on 2012-03-29
5
558 Views
Last Modified: 2012-04-01
Hi,
I have noticed some behaviour of the BackgroundWorker object in C# and want to confirm that what I see is true.
If have a GUI which has a loop to fire off several background workers that are stored in an array. I have for eg. 10 workers and 50 jobs so my gui sits in a loop to check when a worker is not busy and then re-uses that worker to do the next job. All fine.
What I noticed is that if I have no DoEvents in my loop then RunWorkerCompleted never fires and none of my threads ever get isBusy reset, with DoEvents it all works as expected.

1. Apparently using DoEvents is a bad idea although in my scenario it seems to be the best option?
2. I also have a short sleep in the loop to prevent CPU hogging - is this is necessary/good practice?

Pseudo code:

            int jobCount = 30;
            int jobs = 0;
            while (jobs <= jobCount)
            {
                int i = bwFuncs.GetNextThread();
                if (i < 0)
                {
                    Application.DoEvents();
                    Thread.Sleep(50);
                }
                else
                {
                    bwFuncs.threads|i|.RunWorkerAsync();
                    jobs++;
                }
            }
0
Comment
Question by:Alw1n
5 Comments
 
LVL 20

Accepted Solution

by:
BuggyCoder earned 250 total points
ID: 37780811
well i would use a little different approach, i would rather use 1 background worker and inside its run method i would use ThreadPool.QueueUserWorkItem to queue multiple requests...

i would not let the BW return untill all the requests are fulfilled....
Application.DoEvents is not ideal in this situation or rather i would never use it becuase it suspends the current thread and then starts processing the messages, here is a transcript from msdn on DoEvents:-


Calling this method causes the current thread to be suspended while all waiting window messages are processed. If a message causes an event to be triggered, then other areas of your application code may execute. This can cause your application to exhibit unexpected behaviors that are difficult to debug. If you perform operations or computations that take a long time, it is often preferable to perform those operations on a new thread.

read Here:-
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx
0
 

Author Comment

by:Alw1n
ID: 37781099
The background worker is so much easier to use and provides the RunWorkerComplete event which is great. The thing that surprised me was that the backgroundworker threads seem to hang then the calling thread does not give up the time to process RunWorkerComplete.

In my scenario it is preferrable to fire my jobs from a loop and have a bit more control over how they are starting. I have never used the threadpool queue so will need to swat up a bit on that.
0
 
LVL 10

Assisted Solution

by:eguilherme
eguilherme earned 200 total points
ID: 37781243
the code in your pseudo code is running in the gui thread correct?

since the loop will run until all jobs have completed, that Thread.Sleep will cause the GUI thread to hang.. and since the RunWorkerCompletedEvent runs in the GUI thread, the sleep will cause it to hang as well..

what you could try to do so you wont have to make any huge changes in your source code, is to put that pseudo code in another thread (or another background worker) and if try to avoid any calls to any gui controls..
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 50 total points
ID: 37782032
Put your "controller loop" into a master BackgroundWorker() and fire off the other ones from there.  You won't need DoEvents() then since the loop will be on a different thread.

As BuggyCoder suggests, though, the ThreadPool was designed specifically for the kind of thing you described.
0
 

Author Closing Comment

by:Alw1n
ID: 37794736
Thanks for the input everyone, I split the points in order of the replies received. I have ended up using the ThreadPool queue, it doesn't have all the control I was hoping for but seems to work quite well.
fyi I came across the library below which seems to have some cool things although I have not tried it.
http://smartthreadpool.codeplex.com/
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

786 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question