public static async Task CopyToObserveOnTimeAsync(this Stream stream, Stream destination, int bufferSize,
                                                          IObserver <long> progressChangedWatcher, TimeSpan timeSpan)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(bufferSize)} must >= 0.");
            }
            if (progressChangedWatcher == null)
            {
                throw new ArgumentNullException(nameof(progressChangedWatcher));
            }
            if (timeSpan.Milliseconds <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(timeSpan)} must > 0.");
            }

            var copyer = new StreamCopyTimeObserver(stream, destination, bufferSize, progressChangedWatcher, timeSpan);
            await copyer.StartAsync();
        }
        public static async Task CopyToObserveOnTimeAsync(this Stream stream, Stream destination, int bufferSize,
            IObserver<long> progressChangedWatcher, TimeSpan timeSpan)
        {
            if (stream == null) throw new ArgumentNullException(nameof(stream));
            if (destination == null) throw new ArgumentNullException(nameof(destination));
            if (bufferSize <= 0) throw new ArgumentOutOfRangeException($"{nameof(bufferSize)} must >= 0.");
            if (progressChangedWatcher == null) throw new ArgumentNullException(nameof(progressChangedWatcher));
            if (timeSpan.Milliseconds <= 0) throw new ArgumentOutOfRangeException($"{nameof(timeSpan)} must > 0.");

            var copyer = new StreamCopyTimeObserver(stream, destination, bufferSize, progressChangedWatcher, timeSpan);
            await copyer.StartAsync();
        }