/// <summary>The core logic for uploading a stream. It is used by the upload and resume methods.</summary>
        private async Task <IUploadProgress> UploadCoreAsync(CancellationToken cancellationToken)
        {
            try
            {
                using (var callback = new ServerErrorCallback(this))
                {
                    while (!await SendNextChunkAsync(ContentStream, cancellationToken).ConfigureAwait(false))
                    {
                        UpdateProgress(new ResumableUploadProgress(UploadStatus.Uploading, BytesServerReceived));
                    }
                    UpdateProgress(new ResumableUploadProgress(UploadStatus.Completed, BytesServerReceived));
                }
            }
            catch (TaskCanceledException ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Task was canceled", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
                throw ex;
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Exception occurred while uploading media", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
            }

            return(Progress);
        }
        /// <summary>
        /// Uploads the content to the server using the given cancellation token. This method is used for both async 
        /// and sync operation.
        /// </summary>
        private async Task<IUploadProgress> Upload(CancellationToken cancellationToken)
        {
            try
            {
                BytesSent = 0;
                UpdateProgress(new ResumableUploadProgress(UploadStatus.Starting, 0));
                // check if the stream length is known
                StreamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize;
                UploadUri = await InitializeUpload(cancellationToken).ConfigureAwait(false);

                logger.Debug("MediaUpload[{0}] - Start uploading...", UploadUri);

                using (var callback = new ServerErrorCallback(this))
                {
                    while (!await SendNextChunk(ContentStream, cancellationToken).ConfigureAwait(false))
                    {
                        UpdateProgress(new ResumableUploadProgress(UploadStatus.Uploading, BytesSent));
                    }
                    UpdateProgress(new ResumableUploadProgress(UploadStatus.Completed, BytesSent));
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, "MediaUpload[{0}] - Exception occurred while uploading media", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesSent));
            }

            return Progress;
        }
Exemplo n.º 3
0
        /// <summary>Asynchronously resumes the upload form the last point it was interrupted.</summary>
        /// <param name="cancellationToken">A cancellation token to cancel operation.</param>
        public async Task <IUploadProgress> ResumeAsync(CancellationToken cancellationToken)
        {
            if (UploadUri == null)
            {
                Logger.Info("There isn't any upload in progress, so starting to upload again");
                return(await UploadAsync(cancellationToken).ConfigureAwait(false));
            }
            // The first "resuming" request is to query the server in which point the upload was interrupted.
            var range = String.Format("bytes */{0}", StreamLength < 0 ? "*" : StreamLength.ToString());
            HttpRequestMessage request = new RequestBuilder()
            {
                BaseUri = UploadUri,
                Method  = HttpConsts.Put
            }.CreateRequest();

            request.SetEmptyContent().Headers.Add("Content-Range", range);

            try
            {
                HttpResponseMessage response;
                using (var callback = new ServerErrorCallback(this))
                {
                    response = await Service.HttpClient.SendAsync(request, cancellationToken)
                               .ConfigureAwait(false);
                }

                if (await HandleResponse(response).ConfigureAwait(false))
                {
                    // All the media was successfully upload.
                    UpdateProgress(new ResumableUploadProgress(UploadStatus.Completed, BytesServerReceived));
                    return(Progress);
                }
            }
            catch (TaskCanceledException ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Task was canceled", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
                throw ex;
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Exception occurred while resuming uploading media", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
                return(Progress);
            }

            // Continue to upload the media stream.
            return(await UploadCoreAsync(cancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Asynchronously resumes the upload from the last point it was interrupted.
        /// Use when the program was restarted and you wish to resume the upload that was in progress when the program was halted.
        /// Implemented only for ContentStreams where .CanSeek is True.
        /// </summary>
        /// <remarks>
        /// In your application's UploadSessionData Event Handler, store UploadUri.AbsoluteUri property value (resumable session URI string value)
        /// to persistent storage for use with Resume() or ResumeAsync() upon a program restart.
        /// It is strongly recommended that the FullPathFilename of the media file that is being uploaded is saved also so that a subsequent execution of the
        /// program can compare the saved FullPathFilename value to the FullPathFilename of the media file that it has opened for uploading.
        /// You do not need to seek to restart point in the ContentStream file.
        /// </remarks>
        /// <param name="uploadUri">VideosResource.InsertMediaUpload UploadUri property value that was saved to persistent storage during a prior execution.</param>
        /// <param name="cancellationToken">A cancellation token to cancel the asynchronous operation.</param>
        public async Task <IUploadProgress> ResumeAsync(Uri uploadUri, CancellationToken cancellationToken)
        {
            // When called with uploadUri parameter of non-null value, the UploadUri is being
            // provided upon a program restart to resume a previously interrupted upload.
            if (uploadUri != null)
            {
                if (ContentStream.CanSeek)
                {
                    Logger.Info("Resuming after program restart: UploadUri={0}", uploadUri);
                    UploadUri    = uploadUri;
                    StreamLength = ContentStream.Length;
                }
                else
                {
                    throw new NotImplementedException("Resume after program restart not allowed when ContentStream.CanSeek is false");
                }
            }
            if (UploadUri == null)
            {
                Logger.Info("There isn't any upload in progress, so starting to upload again");
                return(await UploadAsync(cancellationToken).ConfigureAwait(false));
            }
            // The first "resuming" request is to query the server in which point the upload was interrupted.
            var range = String.Format("bytes */{0}", StreamLength < 0 ? "*" : StreamLength.ToString());
            HttpRequestMessage request = new RequestBuilder()
            {
                BaseUri = UploadUri,
                Method  = HttpConsts.Put
            }.CreateRequest();

            request.SetEmptyContent().Headers.Add("Content-Range", range);

            try
            {
                HttpResponseMessage response;
                using (var callback = new ServerErrorCallback(this))
                {
                    response = await HttpClient.SendAsync(request, cancellationToken)
                               .ConfigureAwait(false);
                }

                if (await HandleResponse(response).ConfigureAwait(false))
                {
                    // All the media was successfully upload.
                    UpdateProgress(new ResumableUploadProgress(UploadStatus.Completed, BytesServerReceived));
                    return(Progress);
                }
            }
            catch (TaskCanceledException ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Task was canceled", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
                throw ex;
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "MediaUpload[{0}] - Exception occurred while resuming uploading media", UploadUri);
                UpdateProgress(new ResumableUploadProgress(ex, BytesServerReceived));
                return(Progress);
            }

            // Continue to upload the media stream.
            return(await UploadCoreAsync(cancellationToken).ConfigureAwait(false));
        }