private void SignalAndCheck() { if (IsDisposed || _countdown == null) { return; } Monitor.Enter(_countdown); bool completed; try { if (IsDisposed || _countdown == null) { return; } _countdown.Signal(); } finally { completed = _countdown is null or { CurrentCount : < 2 }; } if (completed) { OnWorkCompleted(EventArgs.Empty); _countdown.SignalAll(); } if (_countdown != null) { Monitor.Exit(_countdown); } } }
private void Consume() { if (IsDisposed) { return; } OnWorkStarted(EventArgs.Empty); try { int count = 0; T[] items = new T[Threads]; Task[] tasks = new Task[Threads]; while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { if (!ReadItems(items, ref count) || count < items.Length) { break; } for (int i = 0; !IsDisposed && !Token.IsCancellationRequested && i < items.Length; i++) { T item = items[i]; ScheduledCallback?.Invoke(item); _countdown.AddCount(); tasks[i] = TaskHelper.Run(() => { try { Run(item); } finally { _countdown?.SignalOne(); } }, TaskCreationOptions.PreferFairness, Token); } if (IsDisposed || Token.IsCancellationRequested || !tasks.WaitSilently(Token)) { return; } count = 0; Array.Clear(tasks, 0, tasks.Length); } if (count == items.Length) { count = 0; } TimeSpanHelper.WasteTime(TimeSpanHelper.FAST); while (!IsDisposed && !Token.IsCancellationRequested) { if (!ReadItems(items, ref count) || count < items.Length) { break; } for (int i = 0; !IsDisposed && !Token.IsCancellationRequested && i < items.Length; i++) { T item = items[i]; ScheduledCallback?.Invoke(item); _countdown.AddCount(); tasks[i] = TaskHelper.Run(() => { try { Run(item); } finally { _countdown?.SignalOne(); } }, TaskCreationOptions.PreferFairness, Token); } if (IsDisposed || Token.IsCancellationRequested || !tasks.WaitSilently(Token)) { return; } for (int i = 0; i < tasks.Length; i++) { ObjectHelper.Dispose(ref tasks[i]); } count = 0; Array.Clear(tasks, 0, tasks.Length); } if (count < 1 || IsDisposed || Token.IsCancellationRequested) { return; } Array.Resize(ref tasks, ++count); for (int i = 0; !IsDisposed && !Token.IsCancellationRequested && i < tasks.Length; i++) { T item = items[i]; ScheduledCallback?.Invoke(item); _countdown.AddCount(); tasks[i] = TaskHelper.Run(() => { try { Run(item); } finally { _countdown?.SignalOne(); } }, TaskCreationOptions.PreferFairness, Token); } if (!tasks.WaitSilently(Token)) { return; } for (int i = 0; i < tasks.Length; i++) { ObjectHelper.Dispose(ref tasks[i]); } } finally { OnWorkCompleted(EventArgs.Empty); _countdown.SignalAll(); } }
private void Consume() { if (IsDisposed) { return; } OnWorkStarted(EventArgs.Empty); try { int count = 0; int threads = Threads; if (HasThreshold) { threads++; } Task[] tasks = new Task[threads]; while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { count = 0; if (HasThreshold) { tasks[count++] = Task.Delay(Threshold).ConfigureAwait(); } while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked && count < tasks.Length) { lock (SyncRoot) { if (_queue.IsEmpty) { Monitor.Wait(SyncRoot, TimeSpanHelper.FAST); } if (IsDisposed || Token.IsCancellationRequested || _queue.IsEmpty) { continue; } } while (count < tasks.Length && !IsDisposed && !Token.IsCancellationRequested && !CompleteMarked && !_queue.IsEmpty) { T item; lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { continue; } } _countdown.AddCount(); tasks[count++] = TaskHelper.Run(() => { try { Run(item); } finally { _countdown?.SignalOne(); } }, TaskCreationOptions.PreferFairness, Token); } } if (count < tasks.Length) { break; } if (IsDisposed || Token.IsCancellationRequested || !tasks.WaitSilently(Token)) { return; } for (int i = 0; i < tasks.Length; i++) { ObjectHelper.Dispose(ref tasks[i]); } count = 0; Array.Clear(tasks, 0, tasks.Length); } TimeSpanHelper.WasteTime(TimeSpanHelper.FAST); while (!IsDisposed && !Token.IsCancellationRequested && !_queue.IsEmpty) { if (HasThreshold && count == 0) { tasks[count++] = Task.Delay(Threshold).ConfigureAwait(); } while (count < tasks.Length && !IsDisposed && !Token.IsCancellationRequested && !_queue.IsEmpty) { T item; lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { break; } } _countdown.AddCount(); tasks[count++] = TaskHelper.Run(() => { try { Run(item); } finally { _countdown?.SignalOne(); } }, TaskCreationOptions.PreferFairness, Token); } if (count < tasks.Length) { break; } if (IsDisposed || Token.IsCancellationRequested || !tasks.WaitSilently(Token)) { return; } for (int i = 0; i < tasks.Length; i++) { ObjectHelper.Dispose(ref tasks[i]); } count = 0; Array.Clear(tasks, 0, tasks.Length); } if (count < 1 || IsDisposed || Token.IsCancellationRequested) { return; } Array.Resize(ref tasks, count); tasks.WaitSilently(Token); for (int i = 0; i < tasks.Length; i++) { ObjectHelper.Dispose(ref tasks[i]); } } finally { OnWorkCompleted(EventArgs.Empty); _countdown.SignalAll(); } }