public int Register(SweepTask task) { //Some tasks can generate tasks. Note that this can only be one level deep; nesting compounds is not allowed. //All such generators will be placed at the beginning. var index = count; //This allocates a lot of garbage due to frequently resizing, but it does not matter- task registration a one time thing at program initialization. //Having tight bounds is more useful for performance in the end (by virtue of having a marginally simpler heap). int newCount = count + 1; if (tasks == null || newCount > tasks.Length) { Array.Resize(ref tasks, newCount); } tasks[index] = task; count = newCount; var a = task.ShapeTypeIndexA; var b = task.ShapeTypeIndexB; var highestShapeIndex = a > b ? a : b; if (highestShapeIndex >= topLevelMatrix.Length) { ResizeMatrix(highestShapeIndex + 1); } topLevelMatrix[a][b] = index; topLevelMatrix[b][a] = index; return(index); }
static int Main(string[] args) { if (args.Length < 1) { return(PrintUsage()); } string mode = args[0]; SomeTask[] tasks = null; int threads = 1; try { threads = int.Parse(args[1]); // arg 1: number of threads switch (mode) { case "sweep": { int IE = int.Parse(args[3]); // arg 3: last task (one-based) int I0 = int.Parse(args[2]); // arg 2: first task tasks = new SomeTask[IE - I0 + 1]; for (int i = I0; i <= IE; i++) { tasks[i - I0] = new SweepTask( i - 1, args[4], // arg 4: exe file args[5] // arg 5: control file ); } break; } case "general": { tasks = new SomeTask[args.Length - 2]; for (int i = 2; i < args.Length; i++) { //Console.WriteLine("#" + i + ": " + args[i]); tasks[i - 2] = new GeneralTask(i - 2, args[i].Replace("@@", " ")); } break; } default: return(PrintUsage()); } } catch (Exception) { return(PrintUsage()); } var options = new ParallelOptions() { MaxDegreeOfParallelism = threads }; Parallel.Invoke(options, tasks.Select(t => ((Action)t.Run)).ToArray()); for (int i = 0; i < tasks.Length; i++) { if (!tasks[i].success) { return(i + 1); } } return(0); //tasks[0].RunExample(); }