Solved

BackgroundWorker thread completion and GUI thread interaction

Posted on 2012-03-29
5
556 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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

A basic question.. “What is the Garbage Collector?” The usual answer given back: “Garbage collector is a background thread run by the CLR for freeing up the memory space used by the objects which are no longer used by the program.” I wondered …
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

762 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

Need Help in Real-Time?

Connect with top rated Experts

26 Experts available now in Live!

Get 1:1 Help Now