public static bool DownloadLanguage(string language, ProgressDelegate progress, CompletionDelegate completion) { var localLanguages = LocalLanguages.Where(l => l.Language.Equals(language)); if (localLanguages.Count() > 0) { return(false); } var downloadableLanguages = DownloadableLanguages.Where(l => l.Language.Equals(language)); if (downloadableLanguages.Count() == 0) { return(false); } Task.Run(() => { DownloadLanguageFiles(downloadableLanguages.ElementAt(0).RemotePaths, language, progress, completion); }); return(true); }
private static void DownloadLanguageFiles(Dictionary <string, string> urls, string language, ProgressDelegate progress, CompletionDelegate completion) { OcrLanguage currentlyDownloadingLanguage = null; List <Exception> downloadErrors = new List <Exception>(); bool cancelled = false; try { if (urls.Count == 0) { var downloadableLanguages = DownloadableLanguages.Where(l => l.Language.Equals(language)); if (downloadableLanguages.Count() > 0) { currentlyDownloadingLanguage = downloadableLanguages.ElementAt(0); } completion?.Invoke(currentlyDownloadingLanguage, null); return; } currentlyDownloadingLanguage = GetCurrentlyDownloadingLanguage(urls.Values.ElementAt(0)); if (currentlyDownloadingLanguage != null) { if (currentlyDownloadingLanguage.CancellationTokenSource != null) { currentlyDownloadingLanguage.CancellationTokenSource.Dispose(); currentlyDownloadingLanguage.CancellationTokenSource = null; } currentlyDownloadingLanguage.CancellationTokenSource = new CancellationTokenSource(); currentlyDownloadingLanguage.IsDownloading = true; } long totalSizeToDownload = 0; Task task = null; Dictionary <string, long> totalBytesReceivedForAllDownloads = new Dictionary <string, long>(); List <Task> downloadTasks = new List <Task>(); HttpClientDownloader httpClientDownloader = new HttpClientDownloader(); httpClientDownloader.DownloadCompleted += (object sender, DownloadCompletedEventArgs e) => { if (!e.Cancelled && e.Error == null) { string finalPath = Path.Combine(LanguagesDirectory, Path.GetFileName(e.TargetFilePath)); MoveFile(e.TargetFilePath, finalPath); } else if (e.Cancelled) { cancelled = true; } else if (e.Error != null) { downloadErrors.Add(e.Error); } if (cancelled || e.Error != null) { // Delete temporary file in case or cancellation or error. DeleteFile(e.TargetFilePath); } }; httpClientDownloader.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) => { // if error occurred while downloading any of this language files, then abort the rest. if (downloadErrors.Count > 0) { CancelDownloadForLanguage(currentlyDownloadingLanguage.Language); return; } if (currentlyDownloadingLanguage != null) { if (!currentlyDownloadingLanguage.IsDownloading) { // User cancelled the download of this language return; } long totalBytesReceived = 0; lock (totalBytesReceivedForAllDownloads) { totalBytesReceivedForAllDownloads[e.SourceFileUrl] = e.BytesReceived; foreach (KeyValuePair <string, long> entry in totalBytesReceivedForAllDownloads) { totalBytesReceived += entry.Value; } } currentlyDownloadingLanguage.DownloadPercentage = Math.Round((double)totalBytesReceived / totalSizeToDownload * 100, 2); progress?.Invoke(currentlyDownloadingLanguage, currentlyDownloadingLanguage.DownloadPercentage); } }; void StartDownloadTask(string url) { try { if (downloadErrors.Count > 0) { return; } string targetFilePath = Path.Combine(_downloadLanguagesDirectory, Path.GetFileName(url)); task = httpClientDownloader.DownloadFileAsync(url, targetFilePath, currentlyDownloadingLanguage.CancellationTokenSource?.Token); downloadTasks.Add(task); } catch (Exception ex2) { Console.WriteLine(ex2.Message); } } foreach (KeyValuePair <string, string> entry in urls) { string url = entry.Value; string languageFile = Path.GetFileName(url); string identifier = languageFile.Split('.')[1]; object sizeValue = Manifest[identifier][languageFile][FileSizeKeyString]; if (sizeValue.GetType() == typeof(long)) { totalSizeToDownload += (long)sizeValue; } StartDownloadTask(url); } Task.WaitAll(downloadTasks.ToArray(), -1, (currentlyDownloadingLanguage.CancellationTokenSource != null) ? currentlyDownloadingLanguage.CancellationTokenSource.Token : CancellationToken.None); downloadTasks.Clear(); if (!cancelled) { DownloadableLanguages.Remove(currentlyDownloadingLanguage); LocalLanguages.Add(currentlyDownloadingLanguage); //UpdateLanguagesWithCurrentManifest(); } } catch (Exception ex) { Console.WriteLine(ex.Message); if (ex.GetType() != typeof(TaskCanceledException) && ex.GetType() != typeof(OperationCanceledException) && currentlyDownloadingLanguage != null) { downloadErrors.Add(ex); } } finally { Exception error = null; currentlyDownloadingLanguage.IsDownloading = false; var errors = downloadErrors.Where(e => e != null); if (errors != null && errors.Count() > 0) { error = errors.ElementAt(0); } if (error != null) { DownloadableLanguagesError = error; currentlyDownloadingLanguage.DownloadPercentage = 0; } else { currentlyDownloadingLanguage.DownloadPercentage = 100; } if (!cancelled) { completion?.Invoke(currentlyDownloadingLanguage, error); } } }