private void TryCleanupExistingDownloadWebClient() { if (downloadWebClient == null) { return; } try { lock (this) { if (downloadWebClient != null) { downloadWebClient.DownloadFileCompleted -= OnDownloadCompleted; downloadWebClient.DownloadProgressChanged -= OnDownloadProgressChanged; downloadWebClient.OpenReadCompleted -= OnOpenReadCompleted; downloadWebClient.CancelAsync(); downloadWebClient.Dispose(); downloadWebClient = null; } } } catch (Exception e) { logger.Warn("Error while cleaning up web client : {0}", e.Message); } }
private void TriggerWebClientDownloadFileAsync() { logger.Debug("Falling back to legacy DownloadFileAsync."); try { isFallback = true; string destinationDirectory = Path.GetDirectoryName(localFileName); if (destinationDirectory != null && !Directory.Exists(destinationDirectory)) { Directory.CreateDirectory(destinationDirectory); } TryCleanupExistingDownloadWebClient(); downloadWebClient = CreateWebClient(); downloadWebClient.DownloadFileAsync(fileSource, localFileName); logger.Debug("Download async started. Source: {0} Destination: {1}", fileSource, localFileName); } catch (Exception ex) { logger.Warn("Failed to download Source:{0}, Destination:{1}, Error:{2}.", fileSource, localFileName, ex.Message); if (!AttemptDownload()) { InvokeDownloadCompleted(CompletedState.Failed, localFileName, ex); } } }
private DownloadWebClient CreateWebClient() { DownloadWebClient webClient = new DownloadWebClient(); webClient.DownloadFileCompleted += OnDownloadCompleted; webClient.DownloadProgressChanged += OnDownloadProgressChanged; webClient.OpenReadCompleted += OnOpenReadCompleted; return(webClient); }
private void Download(Uri source, string fileDestination, long totalBytesToReceive) { try { long seekPosition; FileHelpers.TryGetFileSize(fileDestination, out seekPosition); TryCleanupExistingDownloadWebClient(); downloadWebClient = CreateWebClient(); downloadWebClient.OpenReadAsync(source, seekPosition); logger.Debug("Download started. Source: {0} Destination: {1} Size: {2}", source, fileDestination, totalBytesToReceive); } catch (Exception e) { logger.Debug("Download failed: {0}", e.Message); if (!AttemptDownload()) { InvokeDownloadCompleted(CompletedState.Failed, localFileName, e); } } }
private void OnOpenReadCompleted(object sender, OpenReadCompletedEventArgs args) { DownloadWebClient webClient = sender as DownloadWebClient; if (webClient == null) { logger.Warn("Wrong sender in OnOpenReadCompleted: Actual:{0} Expected:{1}", sender.GetType(), typeof(DownloadWebClient)); return; } lock (cancelSync) { if (isCancelled) { logger.Debug("Download was cancelled."); return; } if (!webClient.HasResponse) { logger.Debug("DownloadWebClient returned no response."); TriggerWebClientDownloadFileAsync(); return; } bool appendExistingChunk = webClient.IsPartialResponse; Stream destinationStream = CreateDestinationStream(appendExistingChunk); if (destinationStream != null) { TrySetStreamReadTimeout(args.Result, (int)SourceStreamReadTimeout.TotalMilliseconds); worker = new StreamCopyWorker(); worker.Completed += OnWorkerCompleted; worker.ProgressChanged += OnWorkerProgressChanged; worker.CopyAsync(args.Result, destinationStream, TotalBytesToReceive); } } }
/// <summary> /// OnDownloadCompleted event handler /// </summary> /// <param name="sender">Sender object</param> /// <param name="args">AsyncCompletedEventArgs instance</param> protected void OnDownloadCompleted(object sender, AsyncCompletedEventArgs args) { DownloadWebClient webClient = sender as DownloadWebClient; if (webClient == null) { logger.Warn("Wrong sender in OnDownloadCompleted: Actual:{0} Expected:{1}", sender.GetType(), typeof(DownloadWebClient)); InvokeDownloadCompleted(CompletedState.Failed, localFileName); return; } if (args.Cancelled) { logger.Debug("Download cancelled. Source: {0} Destination: {1}", fileSource, localFileName); if (!isPaused) { DeleteDownloadedFile(); } InvokeDownloadCompleted(CompletedState.Canceled, localFileName); readyToDownload.Set(); } else if (args.Error != null) { if (isFallback) { DeleteDownloadedFile(); } ////We may have NameResolutionFailure on internet connectivity problem. ////We don't use DnsFallbackResolver if we successfully started downloading, and then got internet problem. ////If we change [this.fileSource] here - we lose downloaded chunk in Cache (i.e. we create a new Cache item for new [this.fileSource] if (attemptNumber == 1 && DnsFallbackResolver != null && IsNameResolutionFailure(args.Error)) { Uri newFileSource = DnsFallbackResolver.Resolve(fileSource); if (newFileSource != null) { fileSource = newFileSource; logger.Debug("Download failed in case of DNS resolve error. Retry downloading with new source: {0}.", fileSource); AttemptDownload(); return; } } logger.Debug("Download failed. Source: {0} Destination: {1} Error: {2}", fileSource, localFileName, args.Error); if (!AttemptDownload()) { InvokeDownloadCompleted(CompletedState.Failed, null, args.Error); readyToDownload.Set(); } } else { if (useFileNameFromServer) { localFileName = ApplyNewFileName(localFileName, webClient.GetOriginalFileNameFromDownload()); } logger.Debug("Download completed. Source: {0} Destination: {1}", fileSource, localFileName); if (UseCaching) { downloadCache.Add(fileSource, localFileName, webClient.ResponseHeaders); } ////we may have the destination file not immediately closed after downloading WaitFileClosed(localFileName, TimeSpan.FromSeconds(3)); InvokeDownloadCompleted(CompletedState.Succeeded, localFileName, null); readyToDownload.Set(); } }