Solved

BackgroundWorker thread completion and GUI thread interaction

Posted on 2012-03-29
5
560 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

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