#c_sharp
В предыдущем вопросе, C# Не отображаются проценты при загрузке файла с FTP , мне подсказали данный код. Он работает, однако, я не могу использовать мой прогресс бар. Как я понял, webClient.DownloadProgressChanged выполняется при каждом обновлении, то есть очень быстро и с рандомной частотой. Однако, бывают случаи, когда скрипт еще не успел отработать и по верх него накладывается еще один. Таким образом у меня срывает прогресс бар и появляются лишние символы, которых там быть не должно. Сам вопрос: как мне либо вывести переменную percent выше, в метод Main (что бы оттуда был доступ к ней), либо как мне сделать так, что бы код, находящийся в webClient.DownloadProgressChanged выполнялся не при каждом обновлении скачиваемого файла, а раз, допустим, в 1 секунду? static void Main() { var uriString = @"ftp://user:password@server/Awersome.file"; long totalBytes; var request = (FtpWebRequest)WebRequest.Create(uriString); request.Method = WebRequestMethods.Ftp.GetFileSize; using (var response = request.GetResponse()) { totalBytes = response.ContentLength; } var webClient = new WebClient(); webClient.DownloadProgressChanged += (s, e) => { int percent = (e.BytesReceived * 100 / totalBytes); //другой код }; webClient.DownloadFileCompleted += (s, e) => { }; webClient.DownloadFileAsync(new Uri(uriString), @"D:/1.bin"); }
Ответы
Ответ 1
int previousPercent = 0; webClient.DownloadProgressChanged += (s, e) => { int percent = (e.BytesReceived * 100 / totalBytes); if (percent > previousPercent) { //другой код previousPercent = percent; } };Ответ 2
Вот ещё пример с Reactive Extensions. (Они особенно хороши, когда нужно получить контроль над потоками данных, которыми кто-то «бросается» в вас неудобным образом.) Самое сложное в нём — сконвертировать event в IObservable. async Task DownloadWithConsoleOutput(Uri uri, string savePath) { using (var wc = new WebClient()) { // все сообщения о прогрессе var allEvents = Observable.FromEventPattern( h => wc.DownloadProgressChanged += h, h => wc.DownloadProgressChanged -= h) .Select(p => p.EventArgs); var debouncedEvents = allEvents.Sample(TimeSpan.FromSeconds(1)) // не чаще раза в .DistinctUntilChanged(); // секунду и без повторов // для UI-программ скорее всего понадобится ещё .ObserveOnDispatcher(); // подписываемся на последовательность using (debouncedEvents.Subscribe(args => Console.WriteLine( $"Received: {args.BytesReceived} bytes, {args.ProgressPercentage}%"))) { // запускаем загрузку и дожидаемся окончания await wc.DownloadFileTaskAsync(uri, path); } Console.WriteLine("Download finished"); } }
Комментариев нет:
Отправить комментарий