Пример #1
0
        /// <summary>
        ///     Add progress reporting for the specified response message.
        /// </summary>
        /// <param name="response">
        ///     The HTTP response message.
        /// </param>
        /// <param name="progressSink">
        ///     An optional sink that will receive raw progress data.
        /// </param>
        /// <param name="bufferSize">
        ///     An optional buffer size to use when transferring content.
        ///
        ///     If not specified, the default buffer size is used.
        /// </param>
        /// <returns>
        ///     The response message.
        /// </returns>
        public static HttpResponseMessage AddProgress(this HttpResponseMessage response, IProgressSink <long> progressSink = null, int?bufferSize = null)
        {
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            // No response content? No progress to report.
            // Might be worth creating a dummy sink that just emits 100% progress.
            if (response.Content == null)
            {
                return(response);
            }

            if (response.Content is ProgressContent)
            {
                throw new InvalidOperationException("The HTTP response message has already been configured to report progress.");
            }

            response.Content = new ProgressContent(
                innerContent: response.Content,
                sink: progressSink ?? DefaultSink.Int64(),
                bufferSize: bufferSize
                );

            return(response);
        }
Пример #2
0
        /// <summary>
        ///     Wrap the specified stream in a <see cref="ProgressStream"/> that will report progress for reads.
        /// </summary>
        /// <param name="stream">
        ///     The stream to wrap.
        /// </param>
        /// <param name="total">
        ///     An optional total used to calculate progress.
        ///
        ///     If not specified, the stream length is used (providing the stream supports seeking).
        /// </param>
        /// <param name="progressObserver">
        ///     An optional <see cref="IObserver{TValue}"/> that receives raw progress data.
        /// </param>
        /// <param name="ownsStream">
        ///     Should the <see cref="ProgressStream"/> close the inner stream when it is closed?
        /// </param>
        /// <returns>
        ///     The new <see cref="ProgressStream"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        ///     The <paramref name="stream"/> is already a <see cref="ProgressStream"/>.
        ///     <paramref name="total"/> was not specified, and the stream does not support seeking.
        /// </exception>
        public static ProgressStream WithReadProgress(this Stream stream, long?total = null, IObserver <RawProgressData <long> > progressObserver = null, bool ownsStream = true)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            IProgressSink <long> sink = DefaultSink.Int64();

            if (total.HasValue)
            {
                sink.Total = total.Value;
            }
            else if (stream.CanSeek)
            {
                sink.Total = stream.Length;
            }
            else
            {
                throw new InvalidOperationException("Total was not specified, and cannot be auto-detected because the specified stream does not support seeking.");
            }

            if (progressObserver != null)
            {
                sink.Subscribe(progressObserver);
            }

            return(new ProgressStream(stream, StreamDirection.Read, ownsStream, sink));
        }
Пример #3
0
        /// <summary>
        ///     Add progress reporting for the specified request message.
        /// </summary>
        /// <param name="request">
        ///     The HTTP request message.
        /// </param>
        /// <param name="progressSink">
        ///     An optional sink that will receive raw progress data.
        /// </param>
        /// <param name="bufferSize">
        ///     An optional buffer size to use when transferring content.
        ///
        ///     If not specified, the default buffer size is used.
        /// </param>
        /// <returns>
        ///     The request message.
        /// </returns>
        public static HttpRequestMessage AddProgress(this HttpRequestMessage request, IProgressSink <long> progressSink = null, int?bufferSize = null)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            // No response content? No progress to report.
            if (request.Content == null)
            {
                return(request);
            }

            if (request.Content is ProgressContent)
            {
                throw new InvalidOperationException("The HTTP request message has already been configured to report progress.");
            }

            request.Content = new ProgressContent(
                innerContent: request.Content,
                sink: progressSink ?? DefaultSink.Int64(),
                bufferSize: bufferSize
                );
            request.SetProgressContextId(ProgressContext.Current.Id);

            return(request);
        }
Пример #4
0
        /// <summary>
        ///     Wrap the specified stream in a <see cref="ProgressStream"/> that will report progress for writes.
        /// </summary>
        /// <param name="stream">
        ///     The stream to wrap.
        /// </param>
        /// <param name="total">
        ///     The total used to calculate progress.
        /// </param>
        /// <param name="progressObserver">
        ///     An optional <see cref="IObserver{TValue}"/> that receives raw progress data.
        /// </param>
        /// <param name="ownsStream">
        ///     Should the <see cref="ProgressStream"/> close the inner stream when it is closed?
        /// </param>
        /// <returns>
        ///     The new <see cref="ProgressStream"/>.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        ///     The <paramref name="stream"/> is already a <see cref="ProgressStream"/>.
        /// </exception>
        public static ProgressStream WithWriteProgress(this Stream stream, long total, IObserver <RawProgressData <long> > progressObserver = null, bool ownsStream = true)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            IProgressSink <long> sink = DefaultSink.Int64();

            if (progressObserver != null)
            {
                sink.Subscribe(progressObserver);
            }

            return(new ProgressStream(stream, StreamDirection.Write, ownsStream, sink));
        }