/// <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);
                }
            }
        }
Exemplo n.º 2
0
        /// <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);
        }