private void ScheduleEnumerator(Subscription subscription, IEnumerator <BaseData> enumerator, EnqueueableEnumerator <SubscriptionData> enqueueable, int lowerThreshold, int upperThreshold, int firstLoopCount = 5) { // schedule the work on the controller var security = subscription.Security; var configuration = subscription.Configuration; var firstLoop = true; FuncParallelRunnerWorkItem workItem = null; workItem = new FuncParallelRunnerWorkItem(() => enqueueable.Count < lowerThreshold, () => { var count = 0; while (enumerator.MoveNext()) { // subscription has been removed, no need to continue enumerating if (enqueueable.HasFinished) { enumerator.Dispose(); return; } var subscriptionData = SubscriptionData.Create(configuration, security.Exchange.Hours, subscription.OffsetProvider, enumerator.Current); // drop the data into the back of the enqueueable enqueueable.Enqueue(subscriptionData); count++; // special behavior for first loop to spool up quickly if (firstLoop && count > firstLoopCount) { // there's more data in the enumerator, reschedule to run again firstLoop = false; _controller.Schedule(workItem); return; } // stop executing if we've dequeued more than the lower threshold or have // more total that upper threshold in the enqueueable's queue if (count > lowerThreshold || enqueueable.Count > upperThreshold) { // there's more data in the enumerator, reschedule to run again _controller.Schedule(workItem); return; } } // we made it here because MoveNext returned false, stop the enqueueable and don't reschedule enqueueable.Stop(); }); _controller.Schedule(workItem); }
private void ScheduleEnumerator(IEnumerator <BaseData> enumerator, EnqueueableEnumerator <BaseData> enqueueable, int lowerThreshold, int upperThreshold, int firstLoopCount = 5) { // schedule the work on the controller var firstLoop = true; FuncParallelRunnerWorkItem workItem = null; workItem = new FuncParallelRunnerWorkItem(() => enqueueable.Count < lowerThreshold, () => { var count = 0; while (enumerator.MoveNext()) { // drop the data into the back of the enqueueable enqueueable.Enqueue(enumerator.Current); count++; // special behavior for first loop to spool up quickly if (firstLoop && count > firstLoopCount) { // there's more data in the enumerator, reschedule to run again firstLoop = false; _controller.Schedule(workItem); return; } // stop executing if we've dequeued more than the lower threshold or have // more total that upper threshold in the enqueueable's queue if (count > lowerThreshold || enqueueable.Count > upperThreshold) { // there's more data in the enumerator, reschedule to run again _controller.Schedule(workItem); return; } } // we made it here because MoveNext returned false, stop the enqueueable and don't reschedule enqueueable.Stop(); }); _controller.Schedule(workItem); }