예제 #1
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));
        }
예제 #2
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));
        }