/// <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); } }