示例#1
0
        private async Task <IList <_ThreadProperty> > GetMultipleThreadProperties()
        {
            IList <_ThreadProperty> _out = new List <_ThreadProperty>();

            _TotalSizeToDownload = TryGetContentLength();
            long _SliceSize = _TotalSizeToDownload / _ThreadNumber;
            long _PrevStartSize = 0;
            long?_StartOffset = 0, _EndOffset = 0;

            for (int i = 0; i < (_ThreadSingleMode ? 1 : _ThreadNumber); i++)
            {
                HttpRequestMessage _RequestMessage = new HttpRequestMessage()
                {
                    RequestUri = new Uri(_InputURL)
                };
                _ThreadProperty ThreadProperty = new _ThreadProperty()
                {
                    ThreadID     = i,
                    CurrentRetry = 1,
                    LocalStream  = SeekStreamToEnd(new FileStream(string.Format("{0}.{1:000}", _OutputPath, i + 1), FileMode.OpenOrCreate, FileAccess.Write))
                };
                _DownloadedSize           += ThreadProperty.LocalStream.Length;
                ThreadProperty.StartOffset = _StartOffset = Math.Min(_PrevStartSize, _PrevStartSize += _SliceSize + 1);
                ThreadProperty.EndOffset   = _EndOffset = i + 1 == _ThreadNumber ? _TotalSizeToDownload - 1 : ThreadProperty.StartOffset + _SliceSize;

                ThreadProperty.StartOffset += ThreadProperty.LocalStream.Length;

                if (ThreadProperty.EndOffset - ThreadProperty.StartOffset < -1)
                {
                    Console.WriteLine($"Chunk on ThreadID: {i} seems to be corrupted (< expected size). Redownloading it!");
                    _DownloadedSize            -= ThreadProperty.LocalStream.Length;
                    ThreadProperty.StartOffset -= ThreadProperty.LocalStream.Length;
                    ThreadProperty.LocalStream.Dispose();
                    ThreadProperty.LocalStream = new FileStream(string.Format("{0}.{1:000}", _OutputPath, i + 1), FileMode.Create, FileAccess.Write);
                }

                if (ThreadProperty.EndOffset - ThreadProperty.StartOffset > -1)
                {
                    _RequestMessage.Headers.Range = new RangeHeaderValue(ThreadProperty.StartOffset, ThreadProperty.EndOffset);
                    ThreadProperty.HttpMessage    = CheckResponseStatusCode(await SendAsync(_RequestMessage, HttpCompletionOption.ResponseHeadersRead, _ThreadToken));

                    _out.Add(ThreadProperty);
                }
                else
                {
                    ThreadProperty.LocalStream.Dispose();
                }
            }
            return(_out);
        }
示例#2
0
        private async Task ReadStreamAsync(_ThreadProperty Property)
        {
            int read = 0;

            byte[] buffer = new byte[_DownloadBufferSize];
            while ((read = await Property.RemoteStream.ReadAsync(buffer, 0, buffer.Length, _ThreadToken)) > 0)
            {
                _DownloadedSize    += read;
                _LastContinuedSize += read;
                Property.LocalStream.Write(buffer, 0, read);
                UpdateProgress(new _DownloadProgress(_DownloadedSize, _TotalSizeToDownload, read, _LastContinuedSize, _Stopwatch.Elapsed, _DownloadState));
                Property.CurrentRetry  = 1;
                Property.IsDownloading = true;
            }
        }
示例#3
0
        private async Task <IList <_ThreadProperty> > GetSingleThreadProperties(long?StartOffset, long?EndOffset)
        {
            bool IsIgnore    = false;
            long LocalLength = this._UseStreamOutput ? 0 : _OutputStream.Length;

            HttpRequestMessage RequestMessage = new HttpRequestMessage()
            {
                RequestUri = new Uri(_InputURL)
            };
            _ThreadProperty ThreadProperty = new _ThreadProperty()
            {
                ThreadID     = 0,
                CurrentRetry = 1,
                LocalStream  = this._UseStreamOutput ? _OutputStream : SeekStreamToEnd(_OutputStream),
                StartOffset  = this._UseStreamOutput ? StartOffset ?? 0 : (StartOffset == null ? LocalLength : LocalLength + StartOffset),
                EndOffset    = EndOffset
            };

            _DownloadedSize += LocalLength;

            if (ThreadProperty.EndOffset <= ThreadProperty.StartOffset)
            {
                ThreadProperty.StartOffset = 0;
                ThreadProperty.EndOffset   = EndOffset;
                IsIgnore = true;
            }

            RequestMessage.Headers.Range = new RangeHeaderValue(ThreadProperty.StartOffset, ThreadProperty.EndOffset);

            ThreadProperty.HttpMessage = CheckResponseStatusCode(await SendAsync(RequestMessage, HttpCompletionOption.ResponseHeadersRead, _ThreadToken));

            _TotalSizeToDownload += IsIgnore ? ThreadProperty.HttpMessage.Content.Headers.ContentLength ?? 0 :
                                    (ThreadProperty.HttpMessage.Content.Headers.ContentLength ?? 0) + LocalLength;

            if (IsIgnore)
            {
                return(new List <_ThreadProperty>());
            }

            return(new List <_ThreadProperty> {
                ThreadProperty
            });
        }
示例#4
0
        private async Task <bool> TryRunRetryableTask(_ThreadProperty ThreadProperty, bool IsLastRetry)
        {
            try
            {
                Console.WriteLine($"ThreadID: {ThreadProperty.ThreadID}, Start: {ThreadProperty.StartOffset}, EndOffset: {ThreadProperty.EndOffset}, Size: {ThreadProperty.EndOffset - ThreadProperty.StartOffset}");
                await ReadStreamAsync(ThreadProperty);
            }
            catch (IOException ex)
            {
                Console.WriteLine($"I/O Error on ThreadID: {ThreadProperty.ThreadID}\r\n{ex}");
                if (IsLastRetry)
                {
                    ThreadProperty.LocalStream.Dispose();
                    ThreadProperty.IsDownloading = false;
                    throw new IOException($"ThreadID: {ThreadProperty.ThreadID} has exceeded Max. Retry: {ThreadProperty.CurrentRetry - 1}/{_ThreadMaxRetry}. CANCELLING!!", ex);
                }

                return(false);
            }
            catch (HttpRequestException ex)
            {
                Console.WriteLine($"Error on ThreadID: {ThreadProperty.ThreadID}\r\n{ex}");
                if (IsLastRetry)
                {
                    ThreadProperty.LocalStream.Dispose();
                    ThreadProperty.IsDownloading = false;
                    throw new HttpRequestException($"ThreadID: {ThreadProperty.ThreadID} has exceeded Max. Retry: {ThreadProperty.CurrentRetry - 1}/{_ThreadMaxRetry}. CANCELLING!!", ex);
                }

                return(false);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                ThreadProperty.LocalStream.Dispose();
                ThreadProperty.IsDownloading = false;
                Console.WriteLine($"Cancel: ThreadID: {ThreadProperty.ThreadID} has been shutdown!\r\nChunk of this thread is already completed. Ignoring!!\r\n{ex}");
                return(true);
            }
            catch (InvalidDataException ex)
            {
                ThreadProperty.LocalStream.Dispose();
                ThreadProperty.IsDownloading = false;
                Console.WriteLine($"Cancel: ThreadID: {ThreadProperty.ThreadID} has been shutdown!\r\n{ex}");
                return(true);
            }
            catch (TaskCanceledException ex)
            {
                ThreadProperty.LocalStream.Dispose();
                ThreadProperty.IsDownloading = false;
                Console.WriteLine($"Cancel: ThreadID: {ThreadProperty.ThreadID} has been shutdown!");
                throw new TaskCanceledException(ex.ToString(), ex);
            }
            catch (OperationCanceledException ex)
            {
                ThreadProperty.LocalStream.Dispose();
                ThreadProperty.IsDownloading = false;
                Console.WriteLine($"Cancel: ThreadID: {ThreadProperty.ThreadID} has been shutdown!");
                throw new TaskCanceledException(ex.ToString(), ex);
            }
            catch (Exception ex)
            {
                ThreadProperty.LocalStream.Dispose();
                ThreadProperty.IsDownloading = false;
                Console.WriteLine($"Unknown Error on ThreadID: {ThreadProperty.ThreadID}\r\n{ex}");
                throw new Exception(ex.ToString(), ex);
            }

            return(true);
        }