/// <summary> /// cancel a background task - or prevent a task from running /// </summary> public void Cancel() { lock (_lock) { if (_client != null) { _client.CancelAsync(); } else { // probably an unstarted task or a task that has completed _complete = true; TaskComplete.Set(); } } }
public static void DownloadFileSync(this IWebClient client, Uri address, string filename, CancellationToken cancellationToken) { // Events are only fired when downloading asynchronously with DownloadFileAsync. // This method allows for synchronous downloads while still firing events. // Based on the solution given here: https://stackoverflow.com/a/25834736 (user195275) object mutex = new object(); bool downloadCancelled = false; void handleDownloadComplete(object sender, AsyncCompletedEventArgs e) { downloadCancelled = e.Cancelled; lock (e.UserState) Monitor.Pulse(e.UserState); } client.DownloadFileCompleted += handleDownloadComplete; try { lock (mutex) { using (cancellationToken.Register(() => client.CancelAsync())) { client.DownloadFileAsync(address, filename, mutex); Monitor.Wait(mutex); } } } finally { client.DownloadFileCompleted -= handleDownloadComplete; } if (downloadCancelled) { throw new WebException(Properties.ExceptionMessages.TheRequestWasCancelled, WebExceptionStatus.RequestCanceled); } }
static Timer SetupTransferProgress(IWebClient webClient, ITransferProgress transferProgress) { var lastTime = Tools.Generic.GetCurrentUtcDateTime; long lastBytes = 0; transferProgress.Progress = 0; transferProgress.FileSizeTransfered = 0; webClient.DownloadProgressChanged += (sender, args) => { var bytes = args.BytesReceived; var now = Tools.Generic.GetCurrentUtcDateTime; transferProgress.Progress = args.ProgressPercentage; transferProgress.FileSizeTransfered = bytes; if (lastBytes != 0) { var timeSpan = now - lastTime; var bytesChange = bytes - lastBytes; if (timeSpan.TotalMilliseconds > 0) transferProgress.Speed = (long) (bytesChange/(timeSpan.TotalMilliseconds/1000.0)); } lastBytes = bytes; lastTime = now; }; webClient.DownloadFileCompleted += (sender, args) => { transferProgress.Completed = true; }; var timer = new TimerWithElapsedCancellation(500, () => { if (!transferProgress.Completed && Tools.Generic.LongerAgoThan(lastTime, timeout)) { webClient.CancelAsync(); return false; } return !transferProgress.Completed; }); return timer; }