/// <summary> /// Внутри ожидаем выполнения всех потоков /// </summary> /// <param name="disposing"></param> public virtual void Dispose(bool disposing) { if (!isDisposed) { // запрещаем свершится новым модификациям isDisposing = true; // теперь ожидаем окончания всех текущих модификаций modificationSemaphore.Wait(); modificationSemaphore.Dispose(); // по задаче мы должны дождаться выполнения всех потоков - и тех, которые всё ещё разгребают очередь, // и тех, которых мы уже попросили остановиться, но которые может быть ещё работают. var threads = workingThreads.Concat(cancellingThreads).ToArray(); // вот здесь самое слабое место - мы дожидаемся выполнения остальных задач foreach (var thread in threads) { thread.Join(settings.WaitOnDisposeTimeout); thread.Dispose(); } isDisposed = true; } }
public void Download(string quality, IList <ImageDownloadProgress> allProgress) { var progressEnumerable = allProgress .Where(_ => Str.Equals(_.QualityGroup.Quality, quality)) .OrderBy(getReleaseDate); var commonStack = new ConcurrentStack <ImageDownloadProgress>(); var gdriveStack = new Stack <ImageDownloadProgress>(); var megaStack = new Stack <ImageDownloadProgress>(); foreach (var progress in progressEnumerable) { if (progress.MegaUrl != null && progress.GdriveUrl != null) { commonStack.Push(progress); } else if (progress.MegaUrl != null) { megaStack.Push(progress); } else if (progress.GdriveUrl != null) { gdriveStack.Push(progress); } } Console.WriteLine("Found {0} directories for quality '{1}' in configuration", commonStack.Count + megaStack.Count + gdriveStack.Count, quality); TotalCount = commonStack.Concat(megaStack).Concat(gdriveStack).Sum(_ => _.FilesOnline.Count); _countInDownloadedDirs = 0; ProgressChanged?.Invoke(); var webClient1 = new GdriveWebClient(); var webClient2 = new GdriveWebClient(); void megaFileDownloaded() { Interlocked.Increment(ref _countInDownloadedDirs); ProgressChanged?.Invoke(); } _megatools.FileDownloaded += megaFileDownloaded; Parallel.Invoke( () => download(megaStack, commonStack, downloadFromMega), // google drive delays download start () => download(gdriveStack, commonStack, t => downloadFromGdrive(t, webClient1)), () => download(gdriveStack, commonStack, t => downloadFromGdrive(t, webClient2))); _megatools.FileDownloaded -= megaFileDownloaded; }
internal ImmutableArray <string> GetOutputAndErrorLines() => ReturnIfStopped(() => output.Concat(error).ToImmutableArray());