예제 #1
0
        /// <summary>
        ///   Adds an action to the work queue to run on one of the available threads.
        /// </summary>
        /// <param name="workItem">The action that represents the work item to execute.</param>
        /// <param name="amount">Specifies how many times to execute the <paramref name="workItem"/>.</param>
        /// <remarks>
        ///   It is strongly recommended that the action takes less than a millisecond.
        /// </remarks>
        public void QueueWorkItem([NotNull, Pooled] Action workItem, int amount = 1)
        {
            // Throw right here to help debugging
            if (workItem is null)
            {
                throw new NullReferenceException(nameof(workItem));
            }
            if (amount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(amount));
            }
            if (disposing > 0)
            {
                throw new ObjectDisposedException(ToString());
            }

            Interlocked.Add(ref workScheduled, amount);
            for (int i = 0; i < amount; i++)
            {
                PooledDelegateHelper.AddReference(workItem);
                workItems.Enqueue(workItem);
            }

            semaphore.Release(amount);
        }
        public void QueueWorkItem([NotNull, Pooled] Action workItem, int amount = 1)
        {
            // Throw right here to help debugging
            if (workItem == null)
            {
                throw new NullReferenceException(nameof(workItem));
            }

            if (amount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(amount));
            }

            Interlocked.Add(ref itemCount, amount);

            for (int i = 0; i < amount; i++)
            {
                PooledDelegateHelper.AddReference(workItem);
                queue.Enqueue(workItem);
            }

            if (Volatile.Read(ref idleCount) == 0)
            {
                return;
            }

            lock (lockObj)
            {
                if (Volatile.Read(ref idleCount) == 0)
                {
                    return;
                }

                Monitor.Pulse(lockObj);
            }
        }