0

Необходимо сделать поочередное скачивание каждого файла. С показом текущего имени файла, прогрессом и скоростью. Список файлов я получаю от сервера (JSON), где есть ссылка на каждый файл, путь к нему, куда нужно будет качать и MD5 хэш. Также нужна проверка: если файла нет или md5 хэш не совпадает, качать данный файл.

сейчас же у меня качается только один файл и код выглядит так:

private async void downloadGame(string path) {
#pragma warning disable SYSLIB0014 // Тип или член устарел
        WebClient client = new WebClient();
#pragma warning restore SYSLIB0014 // Тип или член устарел
        Directory.CreateDirectory(DOWNLOADS_PATH);
        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloadGame_DownloadProgressChanged);
        client.DownloadFileCompleted += new AsyncCompletedEventHandler(downloadGame_DownloadFileCompleted!);
        DownloadText = "Скачивание файлов игры...";
        IsDownloading = true;
        if (!sw.IsRunning) {
            sw.Start();
        }
        try {
            await client.DownloadFileTaskAsync(new Uri($@"{API_LINK}/game/{path}"), @$"{DOWNLOADS_PATH}\{path}");
        } catch (WebException e) {
            Dialog.Show("Ошибка скачивания", e.Message);
        }
    }

И проверка файлов:

private async void checkGameUpdates(bool isStartGame = true) {
        DirectoryInfo directoryInfo = new DirectoryInfo(GamePath);
        if(!directoryInfo.Exists) {
            downloadGame();
            return;
        }
        DownloadText = "Проверка файлов игры...";
        IsDownloading = true;
        using (var client = new HttpClient()) {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            try {
                var response = await client.GetFromJsonAsync($"{API_LINK}files.json", typeof(List<GameFileData>));
                if (response is List<GameFileData> file) {
                    int i = 0;
                    while (i < file.Count+1) {
                        if (i == file.Count) {
                            IsDownloading = false;
                            if (!isStartGame) {
                                Dialog.Show("Результат", "Проверка завершена, повреждённых файлов нет.");
                                return;
                            }
                            // start game (gta_sa.exe + samp.exe)
                            DownloadSize = "";
                            DownloadText = "Запуск игры...";
                            Dialog.Show("", "Запуск игры");
                            break;
                        }
                        var path = @$"{GamePath}{file[i].path}".Replace(@"/", @"\");
                        var hash = file[i].md5;
                        DownloadSize = file[i].path;
                        if (File.Exists(path)) {
                            if (hash == "" || await CheckMD5(hash, path)) {
                                i++;
                                DownloadProgress = (int)Math.Ceiling((double)i / file.Count * 100);
                                continue;
                            }
                        }
                        downloadGame(file[i].path);
                        break;
                    }
                } else {
                    Dialog.Show("Ошибка", "ошибка подключения к серверу.");
                }
            } catch (HttpRequestException e) {
                Dialog.Show("Ошибка", "ошибка подключения к серверу: " + e.Message);
                Environment.Exit(0);
            } catch (JsonException e) {
                Dialog.Show("Ошибка", "ошибка JSON: " + e.Message);
                Environment.Exit(0);
            }
        }
    }

Мне нужно переделать скачивание под поочередное.

  • Используйте шаблон проектирования producer/consumer, а WebClient стоит выбросить: 1, 2, 3. Кстати, создание HttpCliet на каждый запрос замедляет его работу и приводит к трате лишних ресурсов, используйте один и тот же клиент для всех запросов. Чтобы что-то здесь переделать, надо научиться не использовать async void и дожидаться завершения скачивания с помощью await. – aepot Oct 14 '23 at 09:39

0 Answers0