jetbet
asked on
How to know when all threads using ThreadWorker class have completed
I have an issue with an application that loads a lot of data into memory and then keeps it updated.
The pipe that we connect through is slow and so I have divided the TCP requests to load individual major components concurrently rather than sequentially.
Each meeting now loads at the same time by creating a meeting object and all sub-objects.
How can I check that all the DoWork() procedures in the ThreadWorker object threads have finished and so the loading is complete from the main thread?
I had thought of creating a List<MeetingCreationWorker > and checking that they had completed using an internal variable. I would then, inside a loop, wait until every variable had been set to a value before moving on.
Does anyone have a better idea?
The MeetingCreationWorker objects and corresponding threads are discarded after the initial load.
The pipe that we connect through is slow and so I have divided the TCP requests to load individual major components concurrently rather than sequentially.
public void SetAllMeetings(Boolean addEvents)
{
try
{
meetings = new List<MeetingDetails>();
string request = Requests.GetGenericString(system, systemId, "Get_Meetings", "All", "", "");
string response = requestStream.GetResponse(request);
XmlDocument xml_doc = new XmlDocument();
xml_doc.LoadXml(response);
XmlNodeList meetingNodes = xml_doc.SelectNodes("Response/Meetings/Meeting");
foreach (XmlNode meeting in meetingNodes)
{
StartMeetingCreationThread(meeting);
}
}
catch (Exception ex)
{
ExceptionStruct temp = new ExceptionStruct(DateTime.Now, "RaceDay", ex.Message, ex.StackTrace.ToString());
exceptionLogger.Add(temp);
}
}
public void StartMeetingCreationThread(XmlNode meeting)
{
MeetingCreationWorker worker = new MeetingCreationWorker(meeting, ref meetings, system, systemId, ref exceptionLogger);
Thread thread = new Thread(worker.DoWork);
thread.Priority = ThreadPriority.Normal;
thread.IsBackground = true;
thread.Start();
}
public class MeetingCreationWorker : ThreadWorker
public override void DoWork()
{
try
{
MeetingDetails temp = new MeetingDetails(updateStream, system, systemId, meeting.SelectSingleNode("Meeting_Number").InnerText, ref exceptionLogger);
temp.SetEventDetails();
meetings.Add(temp);
}
catch (Exception ex)
{
ExceptionStruct temp = new ExceptionStruct(DateTime.Now, "RaceDay", ex.Message, ex.StackTrace.ToString());
exceptionLogger.Add(temp);
}
finally
{
updateStream = null;
}
}
.Each meeting now loads at the same time by creating a meeting object and all sub-objects.
How can I check that all the DoWork() procedures in the ThreadWorker object threads have finished and so the loading is complete from the main thread?
I had thought of creating a List<MeetingCreationWorker
Does anyone have a better idea?
The MeetingCreationWorker objects and corresponding threads are discarded after the initial load.
Ofcourse, before you implement your own Completed event, I would first check to see if the ThreadWorker class you are dealing with implements it's own Completed event. You might find some other useful events that the class implements, i.e Progress, Canceled and such.
-saige-
-saige-
ASKER
Thanks for your input.
The thread worker class is a construct suggested by MS that I use as a base class whenever I need a new Thread.
I have solved the issue using my original idea of adding a Boolean variable to the MeetingCreationWorker and inside the "finally" block of the DoWork() function that I can then Query using the following code on the main thread.
The thread worker class is a construct suggested by MS that I use as a base class whenever I need a new Thread.
I have solved the issue using my original idea of adding a Boolean variable to the MeetingCreationWorker and inside the "finally" block of the DoWork() function that I can then Query using the following code on the main thread.
public void StartMeetingCreationThread(XmlNode meeting)
{
MeetingCreationWorker worker = new MeetingCreationWorker(meeting, ref meetings, system, systemId, showAllRunners, ref raceSportLinks, oddsStoreURL, oddsStoreTimeout, triggerEvents, JetbetDate, ref exceptionLogger);
meetingCreationList.Add(worker);
Thread thread = new Thread(worker.DoWork);
thread.Priority = ThreadPriority.Normal;
thread.IsBackground = true;
thread.Start();
}
// From main thread
....
foreach (XmlNode meeting in meetingNodes)
{
StartMeetingCreationThread(meeting);
}
while (meetingCreationList.Count > 0)
{
for (int i = meetingCreationList.Count - 1; i > -1; i--)
{
if (meetingCreationList[i].finished)
{
meetingCreationList.RemoveAt(i);
}
}
Thread.Sleep(1000);
}
ASKER
I've requested that this question be closed as follows:
Accepted answer: 0 points for jetbet's comment #a40375930
for the following reason:
No better solutions were offered
Accepted answer: 0 points for jetbet's comment #a40375930
for the following reason:
No better solutions were offered
I understand that you used your original idea. However, using an event to trigger the completion of a thread is more efficient then using a Thread.Sleep().
http://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/
-saige-
http://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/
-saige-
ASKER
That is a good point but the issue is that I do not want the process to move on until all Creation Threads have completed their task.
I may have misunderstood your answer on how you suggested this was to be achieved with waiting for the 20 or so triggers.
I may have misunderstood your answer on how you suggested this was to be achieved with waiting for the 20 or so triggers.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for the example.
I have adjusted it for my code and it works great. Hopefully you will get these points.
I have adjusted it for my code and it works great. Hopefully you will get these points.
It was my pleasure.
-saige-
-saige-
Open in new window
-saige-