public int Run() { try { workingThreads.ForEach(thread => thread.Start()); while (!interrupted) { if (tasks.Size() > 2 * concurrency || results.Size() > 2 * concurrency) { Thread.Yield(); continue; } var data = getDataBlock(); if (data == null) { tasks.Stop(); break; } tasks.Enqueue(data); } // join only processing tread and not the result aggregator for (var i = 1; i < workingThreads.Count; i++) { workingThreads[i].Join(); } // notifies the result aggregator thread that no new information would be added and wait for it to finish results.Stop(); workingThreads[0].Join(); } catch (HandledException e) { this.Interrupt(); } catch (Exception e) { Console.WriteLine($"Unhandled exception: {e.Message}"); this.Interrupt(); } return(interrupted ? 1 : 0); }