private void SubscribeTaskForRequestCancellation( AtomicBoolean isCancelled, IProducerContext producerContext) { producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { isCancelled.Value = true; }, () => { }, () => { }, () => { })); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable = new StatefulProducerRunnableImpl <EncodedImage>( consumer, listener, ProducerName, requestId, null, null, null, null, null, null, (result) => { EncodedImage.CloseSafely(result); }, async() => { EncodedImage encodedImage = await GetEncodedImage(imageRequest) .ConfigureAwait(false); if (encodedImage == null) { return(null); } await encodedImage.ParseMetaDataAsync().ConfigureAwait(false); return(encodedImage); }); producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { cancellableProducerRunnable.Cancel(); }, () => { }, () => { }, () => { })); _executor.Execute(cancellableProducerRunnable.Runnable); }
/// <summary> /// Instantiates the <see cref="ProgressiveDecoder"/>. /// </summary> public ProgressiveDecoder( DecodeProducer parent, IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) : base(consumer) { _parent = parent; _producerContext = producerContext; _producerListener = producerContext.Listener; _imageDecodeOptions = producerContext.ImageRequest.ImageDecodeOptions; _isFinished = false; Func <EncodedImage, bool, Task> job = (encodedImage, isLast) => { if (encodedImage != null) { if (_parent._downsampleEnabled) { ImageRequest request = producerContext.ImageRequest; if (_parent._downsampleEnabledForNetwork || !UriUtil.IsNetworkUri(request.SourceUri)) { encodedImage.SampleSize = DownsampleUtil.DetermineSampleSize( request, encodedImage); } } return(DoDecode(encodedImage, isLast)); } return(Task.CompletedTask); }; _jobScheduler = new JobScheduler( _parent._executor, job, _imageDecodeOptions.MinDecodeIntervalMs); _producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { }, () => { }, () => { if (_producerContext.IsIntermediateResultExpected) { _jobScheduler.ScheduleJob(); } }, () => { })); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults(IConsumer <T> consumer, IProducerContext context) { IProducerListener producerListener = context.Listener; string requestId = context.Id; StatefulProducerRunnable <T> statefulRunnable = new StatefulProducerRunnableImpl <T>( consumer, producerListener, PRODUCER_NAME, requestId, (T ignored) => { producerListener.OnProducerFinishWithSuccess(requestId, PRODUCER_NAME, null); _inputProducer.ProduceResults(consumer, context); }, null, null, (_) => { return(default(IDictionary <string, string>)); }, (_) => { return(default(IDictionary <string, string>)); }, () => { return(default(IDictionary <string, string>)); }, null, () => { return(Task.FromResult(default(T))); }); context.AddCallbacks( new BaseProducerContextCallbacks( () => { statefulRunnable.Cancel(); _threadHandoffProducerQueue.Remove(statefulRunnable.Runnable); }, () => { }, () => { }, () => { })); _threadHandoffProducerQueue.AddToQueueOrExecute(statefulRunnable.Runnable); }
internal RepeatedPostprocessorConsumer( PostprocessorConsumer postprocessorConsumer, IRepeatedPostprocessor repeatedPostprocessor, IProducerContext context) : base(postprocessorConsumer) { repeatedPostprocessor.SetCallback(this); context.AddCallbacks( new BaseProducerContextCallbacks( () => { if (Close()) { Consumer.OnCancellation(); } }, () => { }, () => { }, () => { })); }
/// <summary> /// Instantiates the <see cref="TransformingConsumer"/>. /// </summary> public TransformingConsumer( ResizeAndRotateProducer parent, IConsumer <EncodedImage> consumer, IProducerContext producerContext) : base(consumer) { _parent = parent; _isCancelled = false; _producerContext = producerContext; Func <EncodedImage, bool, Task> job = (encodedImage, isLast) => { return(DoTransform(encodedImage, isLast)); }; _jobScheduler = new JobScheduler( _parent._executor, job, MIN_TRANSFORM_INTERVAL_MS); _producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { _jobScheduler.ClearJob(); _isCancelled = true; // This only works if it is safe to discard the output of // previous producer consumer.OnCancellation(); }, () => { }, () => { if (_producerContext.IsIntermediateResultExpected) { _jobScheduler.ScheduleJob(); } }, () => { })); }
internal PostprocessorConsumer( PostprocessorProducer parent, IConsumer <CloseableReference <CloseableImage> > consumer, IProducerListener listener, string requestId, IPostprocessor postprocessor, IProducerContext producerContext) : base(consumer) { _parent = parent; _listener = listener; _requestId = requestId; _postprocessor = postprocessor; producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { MaybeNotifyOnCancellation(); }, () => { }, () => { }, () => { })); }
/// <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()); })); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable = new StatefulProducerRunnableImpl <EncodedImage>( consumer, listener, PRODUCER_NAME, requestId, null, null, null, (result) => { IDictionary <string, string> extraMap = new Dictionary <string, string>() { { CREATED_THUMBNAIL, (result != null).ToString() } }; return(new ReadOnlyDictionary <string, string>(extraMap)); }, null, null, (result) => { EncodedImage.CloseSafely(result); }, async() => { Uri sourceUri = imageRequest.SourceUri; StorageFile file = await StorageFile .GetFileFromApplicationUriAsync(sourceUri) .AsTask() .ConfigureAwait(false); using (var fileStream = await file.OpenReadAsync().AsTask().ConfigureAwait(false)) { byte[] bytes = await BitmapUtil .GetThumbnailAsync(fileStream) .ConfigureAwait(false); if (bytes != null) { IPooledByteBuffer pooledByteBuffer = _pooledByteBufferFactory.NewByteBuffer(bytes); return(await BuildEncodedImage(pooledByteBuffer, fileStream) .ConfigureAwait(false)); } else { return(null); } } }); producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { cancellableProducerRunnable.Cancel(); }, () => { }, () => { }, () => { })); _executor.Execute(cancellableProducerRunnable.Runnable); }