/// <summary> /// Register callbacks to be called when cancellation of consumer /// is requested, or if the prefetch status of the consumer changes. /// </summary> private void AddCallbacks( Tuple <IConsumer <T>, IProducerContext> consumerContextPair, IProducerContext producerContext) { producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { BaseProducerContext contextToCancel = null; IList <IProducerContextCallbacks> isPrefetchCallbacks = null; IList <IProducerContextCallbacks> priorityCallbacks = null; IList <IProducerContextCallbacks> isIntermediateResultExpectedCallbacks = null; bool pairWasRemoved = false; lock (_gate) { object val = default(object); pairWasRemoved = _consumerContextPairs.TryRemove(consumerContextPair, out val); if (pairWasRemoved) { if (_consumerContextPairs.IsEmpty) { contextToCancel = _multiplexProducerContext; } else { isPrefetchCallbacks = UpdateIsPrefetch(); priorityCallbacks = UpdatePriority(); isIntermediateResultExpectedCallbacks = UpdateIsIntermediateResultExpected(); } } } BaseProducerContext.CallOnIsPrefetchChanged(isPrefetchCallbacks); BaseProducerContext.CallOnPriorityChanged(priorityCallbacks); BaseProducerContext.CallOnIsIntermediateResultExpectedChanged( isIntermediateResultExpectedCallbacks); if (contextToCancel != null) { contextToCancel.Cancel(); } if (pairWasRemoved) { consumerContextPair.Item1.OnCancellation(); } }, () => { BaseProducerContext.CallOnIsPrefetchChanged(UpdateIsPrefetch()); }, () => { BaseProducerContext.CallOnIsIntermediateResultExpectedChanged( UpdateIsIntermediateResultExpected()); }, () => { BaseProducerContext.CallOnPriorityChanged(UpdatePriority()); })); }