/// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="scheduler">The scheduler.</param>
        /// <param name="yieldToken">Token to observe for yield requests.</param>
        /// <returns><c>true</c> if the task has been completed; otherwise, <c>false</c>.</returns>
        public bool Execute(IScheduler scheduler, YieldToken yieldToken)
        {
            Debug.Assert(scheduler != null, "Scheduler should not be null.");

            _processor.Process(BatchSize, yieldToken);

            return(false);
        }
Esempio n. 2
0
        public void YieldToken_Basics()
        {
            var s = new MyYieldTokenSource();

            var t = new YieldToken(s);

            foreach (var token in new[]
            {
                t,
                s.Token,
            })
            {
                s.IsYieldRequested = false;
                Assert.IsFalse(token.IsYieldRequested);

                s.IsYieldRequested = true;
                Assert.IsTrue(token.IsYieldRequested);
            }

            var t1 = t;
            var t2 = t;

            Assert.IsTrue(t1.Equals((object)t2));
            Assert.IsFalse(t1.Equals("bar"));

            Assert.IsTrue(t1.Equals(t2));
            Assert.IsTrue(t1 == t2);
            Assert.IsFalse(t1 != t2);

            Assert.IsFalse(t == YieldToken.None);
            Assert.IsFalse(YieldToken.None == t);
            Assert.IsFalse(YieldToken.None.Equals(t));
            Assert.IsFalse(YieldToken.None.Equals((object)t));
            Assert.IsFalse(t.Equals(YieldToken.None));
            Assert.IsFalse(t.Equals((object)YieldToken.None));

            Assert.AreNotEqual(0, t.GetHashCode());
        }
            public void Process(int batchSize, YieldToken token)
            {
                if (token.IsYieldRequested)
                {
                    return;
                }

                bool      completed = default;
                Exception error     = default;
                int       eventCount;

                _itemProcessed = true;

                if (_eventBuffer.Length < batchSize)
                {
                    _eventBuffer = new TResult[batchSize];
                }

                lock (_queue)
                {
                    eventCount = Math.Min(_queue.Count, batchSize);
                    _queue.CopyTo(0, _eventBuffer, 0, eventCount);
                    _queue.RemoveRange(0, eventCount);

                    if (_queue.Count == 0)
                    {
                        completed = _completed;
                        error     = _error;
                    }
                }

                int i;

                for (i = 0; i < eventCount && !token.IsYieldRequested; ++i)
                {
                    var evt = _eventBuffer[i];

                    var success = false;
                    try
                    {
                        _observer.OnNext(evt);
                        success = true;
                        OnDequeued(evt);
                    }
                    catch (Exception ex)
                    {
                        //
                        // Failure to deliver one message is final. We can't retry without triggering duplication of
                        // side-effects on the downstream observers, nor can we skip messages because it'd break the
                        // sequential nature of observable sequences. As such, we can do nothing but terminate.
                        //
                        TraceObserverError("OnNext", ex, evt);
                        throw;
                    }
                    finally
                    {
                        if (!success)
                        {
                            Dispose();
                        }
                    }
                }

                if (i != eventCount)
                {
                    lock (_queue)
                    {
                        _queue.InsertRange(0, _eventBuffer.Take(eventCount).Skip(i));
                    }

                    return;
                }

                if (token.IsYieldRequested)
                {
                    return;
                }

                if (error != null)
                {
                    try
                    {
                        _observer.OnError(error);
                    }
                    catch (Exception ex)
                    {
                        TraceObserverError("OnError", ex, error);
                        throw;
                    }
                    finally
                    {
                        Dispose();
                    }
                }

                if (completed)
                {
                    try
                    {
                        _observer.OnCompleted();
                    }
                    catch (Exception ex)
                    {
                        TraceObserverError("OnCompleted", ex);
                        throw;
                    }
                    finally
                    {
                        Dispose();
                    }
                }
            }
        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="scheduler">The scheduler.</param>
        /// <param name="yieldToken">Token to observe for yield requests.</param>
        /// <returns><c>true</c> if the task has been completed; otherwise, <c>false</c>.</returns>
        public bool Execute(IScheduler scheduler, YieldToken yieldToken)
        {
            Debug.Assert(scheduler != null, "Scheduler should not be null.");

            return(_action(_state, yieldToken));
        }