Reputation: 30847
I have a c# console application which has some threads to do some work (download a file). each thread may exit the application at any time any where in application, but I'll show a proper message on console. It's possible to track them but it doesn't make sense to me. I want simply check thread count or something like that to find out which one is the last thread and do something when it is exiting. What's the best practice to do so ?
pseudo code:
if (lastThread)
{
cleanUp();
Console.ReadLine();
}
Thanks
Upvotes: 5
Views: 249
Reputation: 564413
This is one place where using the new Task Parallel Library can make life much easier. Instead of creating threads, and spinning work up on the thread, you can use multiple tasks:
var task1 = Task.Factory.StartNew( () => DoTaskOneWork() );
var task2 = Task.Factory.StartNew( () => DoTaskTwoWork() );
var task3 = Task.Factory.StartNew( () => DoTaskThreeWork() );
// Block until all tasks are done
Task.WaitAll(new[] {task1, task2, task3} );
cleanUp(); // Do your cleanup
If the "tasks" are just downloading a bunch of individual files, you could even make this simpler using PLINQ:
var fileUrls = GetListOfUrlsToDownload();
fileUrls.AsParallel().ForAll( fileUrl => DownloadAndProcessFile(fileUrl) );
cleanUp(); // Do your cleanup
Upvotes: 11
Reputation: 54148
A design where you lose track of your threads is not ideal.
Depending on how you spawn them it ought to be possible to track the status of each by associating some per-thread signalable object, then WaitAll on those signalable objects.
Each signalable object in turn should get signaled as its thread exits. When they are all signaled, you know the threads are all dead and you close down clean. You have to make sure that abnormal conditions in your threads do not result in that thread's associated signalable object remaining unset, or your WaitAll
will never return. This means exceptions typically - could use try...finally
to ensure the objects get signaled.
Your new pseudocode is
foreach (workitem in list of work)
start up thread associated with a ManualResetEvent or similar
WaitAll for all events to be signalled
cleanup
Upvotes: 2
Reputation: 838186
Your main thread should join with all your worker threads and block while they are running. Then when all threads are complete it performs the cleanup code and then quits.
Alternatively you can use a WaitHandle such as as a ManualResetEvent per thread and wait for all of them to be signalled.
Upvotes: 1