These are always fun questions to ponder, and of course there's multiple ways to solve it.
One approach that's worked well for me is to provide a callback method that each thread uses to pass back results and status. In the following example, I use a List to keep track of running threads and put the results in a Dictionary.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Timers;
namespace ConsoleApplication1
{
class Program
{
static Dictionary threadResults = new Dictionary();
static int threadMax = 2;
static void Main(string[] args)
{
List<Thread> runningThreads = new List<Thread>();
for (int i = 0; i < threadMax; i++)
{
Worker worker = new Worker();
worker.Callback = new Worker.CallbackDelegate(ThreadDone);
Thread workerThread = new Thread(worker.DoSomething);
workerThread.IsBackground = true;
runningThreads.Add(workerThread);
workerThread.Start();
}
foreach (Thread thread in runningThreads) thread.Join();
}
public static void ThreadDone(int threadIdArg, object resultsArg)
{
threadResults[threadIdArg] = resultsArg;
}
}
class Worker
{
public delegate void CallbackDelegate(int threadIdArg, object resultArg);
public CallbackDelegate Callback { get; set; }
public void DoSomething()
{
// do your thing and put it into results
object results = new object();
int myThreadId = Thread.CurrentThread.ManagedThreadId;
Callback(myThreadId, results);
}
}
}