Example #1
0
        /// <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;
            }
        }
Example #2
0
        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());