public bool BuildFast(string projectDir, int processorCount) { Process[] slots = new Process[processorCount]; using (var sw = new StreamWriter(Path.Combine(projectDir, "build.log"))) { foreach (var task in CompileTasks) { int firstEmptySlot; for (;;) { firstEmptySlot = Enumerable.Range(0, slots.Length).FirstOrDefault(i => slots[i]?.HasExited != false); if (slots[firstEmptySlot]?.HasExited == false) { WaitForMultipleObjects(slots.Length, slots.Select(s => s.Handle).ToArray(), false, Timeout.Infinite); continue; } break; } if (slots[firstEmptySlot] != null && slots[firstEmptySlot].ExitCode != 0) { // Wait for other tasks completion IntPtr[] remaining = slots.Where(s => s?.HasExited == false).Select(s => s.Handle).ToArray(); WaitForMultipleObjects(remaining.Length, remaining, true, Timeout.Infinite); return false; //Exited with error } slots[firstEmptySlot] = task.Start(projectDir, firstEmptySlot, sw); } IntPtr[] remainingProcesses = slots.Where(s => s?.HasExited == false).Select(s => s.Handle).ToArray(); WaitForMultipleObjects(remainingProcesses.Length, remainingProcesses, true, Timeout.Infinite); foreach (var slot in slots) { if (slot != null && slot.ExitCode != 0) return false; //Exited with error } foreach (var task in OtherTasks) { var proc = task.Start(projectDir, 0, sw); proc.WaitForExit(); if (proc.ExitCode != 0) return false; } } return true; }