Perform processing in separate worker instances, each in its own thread. Use the callback to return the results and the process call signal that the thread is running. Use the dictionary to keep track of current threads. If you have many threads, you should load the queue and start new threads as the old ones end. In this example, all threads are created before they are launched, in order to prevent a race condition when the number of started threads drops to zero before the final threads start.
Dictionary<int, Thread> activeThreads = new Dictionary<int, Thread>(); void LaunchWorkers() { foreach (var task in tasks) { Worker worker = new Worker(task, new WorkerDoneDelegate(ProcessResult)); Thread thread = new Thread(worker.Done); thread.IsBackground = true; activeThreads.Add(thread.ManagedThreadId, thread); } lock (activeThreads) { activeThreads.Values.ToList().ForEach(n => n.Start()); } } void ProcessResult(int threadId, TResult result) { lock (results) { results.Add(result); } lock (activeThreads) { activeThreads.Remove(threadId);
source share