/// <summary>
        /// use two thread to read/write stream.
        /// this method was testing, no not use to release.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="destination"></param>
        /// <param name="bufferSize"></param>
        /// <param name="progressChangedWatcher"></param>
        /// <param name="poolSize"></param>
        /// <returns></returns>
        public static async Task DoubleThreadCopyToAsync(this Stream stream, Stream destination, int bufferSize,
                                                         IObserver <long> progressChangedWatcher, int poolSize = 20)
        {
            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 (poolSize <= 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(poolSize)} must > 0.");
            }

            using (var copyer = new DoubleThreadStreamCopyer(stream, destination, bufferSize, poolSize, progressChangedWatcher))
                await copyer.Start();
        }
        /// <summary>
        /// use two thread to read/write stream.
        /// this method was testing, no not use to release.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="destination"></param>
        /// <param name="bufferSize"></param>
        /// <param name="progressChangedWatcher"></param>
        /// <param name="poolSize"></param>
        /// <returns></returns>
        public static async Task DoubleThreadCopyToAsync(this Stream stream, Stream destination, int bufferSize,
            IObserver<long> progressChangedWatcher, int poolSize = 20)
        {
            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 (poolSize <= 0) throw new ArgumentOutOfRangeException($"{nameof(poolSize)} must > 0.");

            using (var copyer = new DoubleThreadStreamCopyer(stream, destination, bufferSize, poolSize, progressChangedWatcher))
                await copyer.Start();
        }