/// <summary> /// Begins a stream copy operation. /// /// This method wraps the StartCopyStreamAsync method, presenting a different API for it. /// As we update the library to be more task-based, callers should gradually move to StartCopyStreamAsync. /// </summary> /// <param name="completedDelegate">Callback delegate</param> /// <param name="copyLength">Number of bytes to copy from source stream to destination stream. Cannot pass in both copyLength and maxLength.</param> /// <param name="maxLength">Maximum length of the source stream. Cannot pass in both copyLength and maxLength.</param> /// <param name="cancellationToken">The cancellation token for the operation.</param> public Task StartCopyStream(Action <ExecutionState <T> > completedDelegate, long?copyLength, long?maxLength, CancellationToken cancellationToken) { Task streamCopyTask = this.StartCopyStreamAsync(copyLength, maxLength, cancellationToken); streamCopyTask.ContinueWith(completedStreamCopyTask => { this.state.CancelDelegate = this.previousCancellationDelegate; if (completedStreamCopyTask.IsFaulted) { this.state.ExceptionRef = completedStreamCopyTask.Exception.InnerException; } else if (completedStreamCopyTask.IsCanceled) { bool timedOut = false; try { timedOut = !this.cancellationTokenSourceAbort.IsCancellationRequested; if (!timedOut && this.cancellationTokenSourceTimeout != null) { // Free up the OS timer as soon as possible. this.cancellationTokenSourceTimeout.Dispose(); } } catch (Exception) { // No-op, we want to propagate the cancellation/timeout exception, not whatever may have happened here. } try { if (state.Req != null) { try { state.ReqTimedOut = timedOut; #if WINDOWS_DESKTOP || WINDOWS_PHONE state.CancellationTokenSource.Cancel(); #endif } catch (Exception ex) { Logger.LogWarning(state.OperationContext, "Aborting the request failed with exception: {0}", ex); } } } catch (Exception) { // No-op, we want to propagate the cancellation/timeout exception, not whatever may have happened here. } this.state.ExceptionRef = timedOut ? Exceptions.GenerateTimeoutException(state.Cmd != null ? state.Cmd.CurrentResult : null, null) : Exceptions.GenerateCancellationException(state.Cmd != null ? state.Cmd.CurrentResult : null, null); } try { if (completedDelegate != null) { completedDelegate(this.state); } } catch (Exception ex) { this.state.ExceptionRef = ex; } this.Dispose(); }); return(streamCopyTask); }