public DataFlowQueue([NotNull] ProducerConsumerQueueOptions <T> options, CancellationToken token = default(CancellationToken)) : base(options, token) { _workCompletedEventSlim = new ManualResetEventSlim(false); // Define the mesh. _queue = new BufferBlock <T>(new DataflowBlockOptions { CancellationToken = Token }); _processor = new ActionBlock <T>(e => { ScheduledCallback?.Invoke(e); Run(e); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Threads, CancellationToken = Token }); _link = _queue.LinkTo(_processor, new DataflowLinkOptions { PropagateCompletion = true }); Task.Run(Consume).ConfigureAwait(); }
private void Consume() { _workStartedEvent.Set(); if (IsDisposed) { return; } try { T item; while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked && _queue.IsEmpty) { _queueEvent.WaitOne(TimeSpanHelper.FAST, Token); } if (IsDisposed || Token.IsCancellationRequested) { return; } if (CompleteMarked) { break; } lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { continue; } } ScheduledCallback?.Invoke(item); Run(item); } while (!IsDisposed && !Token.IsCancellationRequested && !_queue.IsEmpty) { // no lock here if (!_queue.TryDequeue(out item)) { continue; } ScheduledCallback?.Invoke(item); Run(item); } } finally { SignalAndCheck(); } }
private void Consume() { _workStartedEvent.Set(); if (IsDisposed) { return; } try { while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked && !_queue.IsCompleted) { while (!IsDisposed && !Token.IsCancellationRequested && _queue.Count > 0) { if (!_queue.TryTake(out T item, TimeSpanHelper.FAST, Token)) { continue; } ScheduledCallback?.Invoke(item); Run(item); } } if (IsDisposed || Token.IsCancellationRequested) { return; } foreach (T item in _queue.GetConsumingEnumerable(Token)) { ScheduledCallback?.Invoke(item); Run(item); } } catch (ObjectDisposedException) { } catch (OperationCanceledException) { } finally { SignalAndCheck(); } }
private void Consume() { if (IsDisposed) { return; } OnWorkStarted(EventArgs.Empty); Task[] tasks = new Task[Threads]; Interlocked.Exchange(ref _running, 0); try { while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { T item; lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { continue; } } int index = Array.FindIndex(tasks, e => e == null || e.IsFinished()); if (tasks[index] != null) { // reuse finished task slot ObjectHelper.Dispose(ref tasks[index]); tasks[index] = null; Interlocked.Decrement(ref _running); } ScheduledCallback?.Invoke(item); tasks[index] = TaskHelper.Run(() => ExecRun(item), TaskCreationOptions.PreferFairness, Token).ConfigureAwait(); Interlocked.Increment(ref _running); // don't wait until all slots are filled if (_running < Threads) { continue; } Task.WaitAny(tasks, Token); } if (Token.IsCancellationRequested) { return; } TimeSpanHelper.WasteTime(TimeSpanHelper.FAST); while (!IsDisposed && !Token.IsCancellationRequested) { T item; lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { break; } } int index = Array.FindIndex(tasks, e => e == null || e.IsFinished()); if (tasks[index] != null) { // reuse finished task slot ObjectHelper.Dispose(ref tasks[index]); tasks[index] = null; Interlocked.Decrement(ref _running); } ScheduledCallback?.Invoke(item); tasks[index] = TaskHelper.Run(() => ExecRun(item), TaskCreationOptions.PreferFairness, Token).ConfigureAwait(); Interlocked.Increment(ref _running); // don't wait until all slots are filled if (_running < Threads) { continue; } Task.WaitAny(tasks, Token); } if (_running == 0) { return; } int firstNullIndex = Array.FindIndex(tasks, e => e == null); if (firstNullIndex > -1) { Array.Resize(ref tasks, firstNullIndex + 1); } Task.WaitAll(tasks, Token); Interlocked.Exchange(ref _running, 0); } finally { OnWorkCompleted(EventArgs.Empty); _allWorkDone?.Set(); } }
private void Consume() { _workStartedEvent.Set(); if (IsDisposed) { return; } object lck = GetLock(); try { T item; while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked && _queue.IsEmpty) { lock (lck) Monitor.Wait(lck, TimeSpanHelper.FAST); } if (IsDisposed || Token.IsCancellationRequested) { return; } if (CompleteMarked) { break; } lock (lck) { if (IsDisposed || Token.IsCancellationRequested) { return; } if (CompleteMarked) { break; } if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { continue; } } ScheduledCallback?.Invoke(item); Run(item); } while (!IsDisposed && !Token.IsCancellationRequested && !_queue.IsEmpty) { lock (lck) { if (IsDisposed || Token.IsCancellationRequested) { return; } if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { break; } } ScheduledCallback?.Invoke(item); Run(item); } } finally { SignalAndCheck(); } }
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); IList <Thread> threads = new List <Thread>(Threads); try { T item; while (!IsDisposed && !Token.IsCancellationRequested && !CompleteMarked) { lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { continue; } } ScheduledCallback?.Invoke(item); Thread thread = new Thread(RunThread) { IsBackground = IsBackground, Priority = Priority }; if (_countdown == null) { _countdown = new CountdownEvent(2); } else { _countdown.AddCount(); } thread.Start(item); threads.Add(thread); if (threads.Count < Threads) { continue; } _countdown.Signal(); _countdown.Wait(Token); threads.Clear(); ObjectHelper.Dispose(ref _countdown); } TimeSpanHelper.WasteTime(TimeSpanHelper.FAST); while (!IsDisposed && !Token.IsCancellationRequested) { lock (SyncRoot) { if (_queue.IsEmpty || !_queue.TryDequeue(out item)) { break; } } ScheduledCallback?.Invoke(item); Thread thread = new Thread(RunThread) { IsBackground = IsBackground, Priority = Priority }; if (_countdown == null) { _countdown = new CountdownEvent(2); } else { _countdown.AddCount(); } thread.Start(item); threads.Add(thread); if (threads.Count < Threads) { continue; } _countdown.Signal(); _countdown.Wait(Token); threads.Clear(); ObjectHelper.Dispose(ref _countdown); } if (_countdown is not { CurrentCount : > 1 }) { return; } _countdown.Signal(); _countdown.Wait(Token); }