Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

BackgroundWorker thread completion and GUI thread interaction

Posted on 2012-03-29
5
Medium Priority
?
567 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 1000 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 800 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 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 200 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

Python: Series & Data Frames With Pandas

Learn the basics of Python’s pandas library of series & data frames and how we can use these tools for data manipulation.

Question has a verified solution.

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

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

704 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