Example #1
0
        /// <summary>
        ///     Start consuming.
        /// </summary>
        public void Start()
        {
            // all tasks scheduled in a background thread
            Task.Run(() => {
                var empty = false;
                // used to handle cancellation requests
                var parallelOptions = new ParallelOptions {
                    CancellationToken = _cts.Token
                };
                try {
                    // a parallel iteration on _workers.
                    // workers work on different threads, or even different CPU cores.
                    Parallel.ForEach(_workers, parallelOptions, worker => {
                        // try dequeue a product
                        TProduct raw;
                        while (_queue.TryTake(out raw, _waitProducerMsTimeout))
                        {
                            // cancel if stopped
                            parallelOptions.CancellationToken.ThrowIfCancellationRequested();
                            // process data asynchronously
                            var result = ConsumeElement(raw, worker);
                            // handle results synchronously
                            lock (this) {
                                parallelOptions.CancellationToken.ThrowIfCancellationRequested();
                                // handle the result
                                _syncResultHandleFunc(result);
                                ConsumedCnt++;
                                Update?.Invoke(result);
                                if (result.IsSuccessful)
                                {
                                    _continuousFailCnt = 0;
                                }
                                else
                                {
                                    _continuousFailCnt++;
                                    if (_continuousFailCnt >= 10)
                                    {
                                        SourceInvalid?.Invoke();
                                        return;
                                    }
                                }

                                if (ConsumedCnt >= TargetCnt.GetValueOrDefault(int.MaxValue))
                                {
                                    TargetAmountReached?.Invoke();
                                    return;
                                }
                            }
                        }
                        empty = true;
                    });
                    if (empty)
                    {
                        ProducerEmpty?.Invoke();
                    }
                } catch (OperationCanceledException) {
                    // tasks stopped
                }
            });
        }
Example #2
0
 /// <summary>
 ///     Start consuming.
 /// </summary>
 public void Start()
 {
     Task.Run(() => {
         while (!_cancellationTokenSource.IsCancellationRequested)
         {
             Thread.Sleep(100);
             TProduct raw;
             if (!_queue.TryTake(out raw, _waitProducerTimeoutMs))
             {
                 ProducerEmpty?.Invoke();
                 break;
             }
             if (_cancellationTokenSource.IsCancellationRequested)
             {
                 return;
             }
             var result = ConsumeElement(raw);
             Update?.Invoke(result);
             if (result.IsSuccessful)
             {
                 _continuousFailCnt = 0;
             }
             else
             {
                 _continuousFailCnt++;
                 if (_continuousFailCnt >= 10)
                 {
                     SourceInvalid?.Invoke();
                     break;
                 }
             }
             ConsumedCnt++;
             if (ConsumedCnt >= TargetCnt.GetValueOrDefault(int.MaxValue))
             {
                 TargetAmountReached?.Invoke();
             }
         }
     }, _cancellationTokenSource.Token);
 }