public void DownloadHandler (MainProgramElements mainWindow) { #region Initialization mainWindow.WindowEnabled = false; mainWindow.CurrentDownloadOutputText = "Starting Downloading Process...."; int selectedIndex = mainWindow.CurrentlySelectedQueueIndex; var urlList = mainWindow.Videos.ToList().AsReadOnly(); urlList.WriteToFile(Storage.QueueFile, ".bak"); List<Video> finishedVideos = new List<Video>(); int[] retryCount = new int[urlList.Count + 1]; const int maxRetrys = 4; Thread.Sleep(1000); #endregion #region Handle Download Cycle int position = 0, urlListCount = urlList.Count; while (position < urlListCount) { bool exceptionWasCaught = false; bool ableToRetryOnFail = retryCount[position] < maxRetrys; var video = urlList[position]; try { mainWindow.CurrentlySelectedQueueIndex = position; if (retryCount[position] <= 0) { mainWindow.CurrentDownloadOutputText = string.Format(CultureInfo.InstalledUICulture, "Beginning download from '{0}'", video.Location); } mainWindow.CurrentDownloadProgress = 0; //var result = await Task.Run(() => Download.SetupDownload(video, mainWindow)); var result = this.SetupDownload(video, mainWindow); if (result is DownloadCanceledException) { mainWindow.CurrentDownloadOutputText = result.Message; if (App.IsDebugging) result.Message.Log("Youtube Download Helper"); Thread.Sleep(!UserSettings.ContinueOnFail ? 1000 : 850); } else if (result != null) throw result; finishedVideos.Add(video); } catch (Exception ex) { exceptionWasCaught = true; var exceptionMessage = ex.Message; retryCount[position] += ex is NotSupportedException ? maxRetrys + 1 : 1; if (ableToRetryOnFail) { mainWindow.CurrentDownloadOutputText = string.Format(CultureInfo.InstalledUICulture, "URL {0}: {1}. Retrying.... ({2}/{3})", video.Position, exceptionMessage.Truncate(50), (retryCount[position]).ToString(CultureInfo.CurrentCulture), maxRetrys); } else if (!UserSettings.ContinueOnFail) { mainWindow.CurrentDownloadOutputText = exceptionMessage.Truncate(100); ex.Log(GenericCondition.None); break; } if(!UserSettings.ContinueOnFail) { Thread.Sleep(850); } } if (!exceptionWasCaught || (!ableToRetryOnFail && UserSettings.ContinueOnFail)) position++; } #endregion #region Final Steps bool noMajorErrors = retryCount.All(count => count <= maxRetrys); if (noMajorErrors || (!noMajorErrors && finishedVideos.Count() > 5)) { IEnumerable<Video> leftOverVideos = urlList.Where(url => finishedVideos.All(finishedUrl => !url.ToString().Equals(finishedUrl.ToString()))); leftOverVideos.Sort(); mainWindow.Videos = new ObservableCollection<Video>(leftOverVideos); } if (noMajorErrors) mainWindow.CurrentDownloadOutputText = "Finished!"; else if (string.IsNullOrWhiteSpace(mainWindow.CurrentDownloadOutputText)) { mainWindow.CurrentDownloadOutputText = "An Error Has Occurred!"; } if (mainWindow.Videos.Any()) { mainWindow.RefreshQueue(mainWindow.Videos, selectedIndex > mainWindow.Videos.All() ? 0 : selectedIndex); } mainWindow.Videos.WriteToFile(Storage.QueueFile); mainWindow.WindowEnabled = true; #endregion }