/// <summary>
        /// Write a chunk of data using the UploadChunkRequest.
        /// </summary>
        /// <param name="request">The UploadChunkRequest to make the request with.</param>
        /// <param name="readBuffer">The byte[] content to read from.</param>
        /// <param name="exceptionTrackingList">A list of exceptions to use to track progress. ChunkedUpload may retry.</param>
        /// <returns></returns>
        public virtual async Task <UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, byte[] readBuffer, ICollection <Exception> exceptionTrackingList)
        {
            var firstAttempt = true;

            this.uploadStream.Seek(request.RangeBegin, SeekOrigin.Begin);
            await this.uploadStream.ReadAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false);

            while (true)
            {
                using (var requestBodyStream = new MemoryStream(request.RangeLength))
                {
                    await requestBodyStream.WriteAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false);

                    requestBodyStream.Seek(0, SeekOrigin.Begin);

                    try
                    {
                        return(await request.PutAsync(requestBodyStream).ConfigureAwait(false));
                    }
                    catch (ServiceException exception)
                    {
                        if (exception.IsMatch("generalException") || exception.IsMatch("timeout"))
                        {
                            if (firstAttempt)
                            {
                                firstAttempt = false;
                                exceptionTrackingList.Add(exception);
                            }
                            else
                            {
                                throw;
                            }
                        }
                        else if (exception.IsMatch("invalidRange"))
                        {
                            // Succeeded previously, but nothing to return right now
                            return(new UploadChunkResult());
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Get the series of requests needed to complete the upload session. Call <see cref="UpdateSessionStatusAsync"/>
        /// first to update the internal session information.
        /// </summary>
        /// <param name="options">Options to be applied to each request.</param>
        /// <returns>All requests currently needed to complete the upload session.</returns>
        public virtual IEnumerable <UploadChunkRequest> GetUploadChunkRequests(IEnumerable <Option> options = null)
        {
            foreach (var range in this.rangesRemaining)
            {
                var currentRangeBegins = range.Item1;

                while (currentRangeBegins <= range.Item2)
                {
                    var nextChunkSize = NextChunkSize(currentRangeBegins, range.Item2);
                    var uploadRequest = new UploadChunkRequest(
                        this.Session.UploadUrl,
                        this.client,
                        options,
                        currentRangeBegins,
                        currentRangeBegins + nextChunkSize - 1,
                        this.totalUploadLength);

                    yield return(uploadRequest);

                    currentRangeBegins += nextChunkSize;
                }
            }
        }
示例#3
0
 public virtual async Task <UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, byte[] readBuffer, ICollection <Exception> exceptionTrackingList)
 {
     return(await this.GetChunkRequestResponseAsync(request, exceptionTrackingList));
 }