/// <summary> /// Enqueue a list of actions to be performed concurrently; calls continuation(continuationArgument) when all completed /// </summary> public static void ForEachAction(string name, ReadOnlySpan <Action <object> > works, object argument, Action <object> continuation, object continuationArgument) { CoreException.Assert(s_workers != null, "JobService not initialized"); int numJobs = works.Length; if (numJobs == 0) { return; } if (numJobs == 1) { lock (s_instances) EnqueueInternal(name, works[0], argument); return; } var completion = JobCompletion.Acquire(); completion.ContinuationAtCount = numJobs; completion.Continuation = continuation; completion.ContinuationArgument = continuationArgument; #if DEBUG completion.ContinuationName = name + "Contd"; #endif lock (s_instances) { foreach (var work in works) { EnqueueInternal(name, work, argument, completion); } } }
/// <summary> /// Enqueue work to be called once per argument in list; blocks until all completed /// </summary> public static void ForEachArgumentBlock <TArg>(string name, Action <object> work, ReadOnlySpan <TArg> arguments) { CoreException.Assert(s_workers != null, "JobService not initialized"); if (arguments.Length == 0) { return; } if (arguments.Length == 1) { work(arguments[0]); return; } int numJobs = arguments.Length - 1; var completion = JobCompletion.Acquire(); lock (s_instances) { foreach (var argument in arguments.Slice(1)) { EnqueueInternal(name, work, argument, completion); } } // run one time on this thread using (new Timing(name)) work(arguments[0]); // then, try to steal relevant jobs if possible // am I running within a job? try fetching the JobWorker for this thread var localWorker = JobWorker.WorkerForThread; while (JobService.ExecuteAnyJob(localWorker, completion)) { ; } completion.WaitAndRelease(numJobs); }
/// <summary> /// Enqueue a list of actions to be performed concurrently; calls continuation(continuationArgument) when all completed /// </summary> public static void ForEachActionBlock(string name, ReadOnlySpan <Action <object> > works, object argument) { CoreException.Assert(s_workers != null, "JobService not initialized"); if (works.Length == 0) { return; } if (works.Length == 1) { works[0](argument); return; } int numJobs = works.Length - 1; var completion = JobCompletion.Acquire(); lock (s_instances) { foreach (var work in works.Slice(1)) { EnqueueInternal(name, work, argument, completion); } } // run one time on this thread using (new Timing(name)) works[0](argument); // then, try to steal relevant jobs if possible while (JobService.ExecuteAnyJob(null, completion)) { ; } completion.WaitAndRelease(numJobs); }