Async / Task / Await: Await на самом деле не ждет - PullRequest
0 голосов
/ 25 сентября 2018

Я реализую метод для загрузки нескольких файлов друг за другом.

Я хочу, чтобы метод был асинхронным, поэтому я не блокирую пользовательский интерфейс.

Это метод для загрузкиодин файл и возвращаю задачу загрузки в вышестоящий метод, который загружает все файлы (далее).

public Task DownloadFromRepo(String fileName)
        {
            // Aktuellen DateiNamen anzeigen, fileName publishing for Binding
            CurrentFile = fileName;
            // Einen vollqualifizierten Pfad erstellen, gets the path to the file in AppData/TestSoftware/
            String curFilePath = FileSystem.GetAppDataFilePath(fileName);
            // Wenn die Datei auf dem Rechner liegt, wird sie vorher gelöscht / Deletes the file on the hdd
            FileSystem.CleanFile(fileName);
            using (WebClient FileClient = new WebClient())
            {
                FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((s, e) =>
                {
                    Progress++;
                });
                // Wenn der Download abgeschlossen ist.
                FileClient.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler((s, e) =>
                {

                });
                // Den DOwnload starten
                return FileClient.DownloadFileTaskAsync(new System.Uri(RepoDir + fileName), curFilePath);
            }
        }

Здесь я просто создаю IEnumerable<Task> из всех файлов в FilesToDownload.

public async void DownloadFiles()
        {
            // Angeben, dass der Download nun aktiv ist / Show active binding
            Active = true;
            // Den Fortschritt zurücksetzen / Set Progress to 0 (restarting download)
            Progress = 0;
            // Die bereits heruntergeladenen Dateien schließen. / Clear Downloads
            DownloadedFiles.Clear();
            // Alle Downloads starten und auf jeden einzelnen warten
            await Task.WhenAll(FilesToDownload.Select(file => DownloadFromRepo(file)));
        }

И, наконец, я хочу вызвать метод следующим образом:

private void RetrieveUpdate()
        {
            UpdateInformationDownload.DownloadFiles();
            AnalyzeFile();
        }

Проблема в том, что метод RetrieveUpdate() пропускает AnalyzeFile(), а затемпытается получить доступ к файлам, которые загружаются в данный момент ..

NEED Я хочу иметь возможность позвонить UpdateInformationDownload.DownloadFiles(), дождаться его завершения (это означает, что он загрузил всефайлы), а затем продолжить синхронизацию с AnalyzeFile().

Как мне этого добиться?Я уже искал много ресурсов в Интернете и нашел несколько объяснений и документов Microsoft, но я думаю, что не прошел через схему использования async / await.

1 Ответ

0 голосов
/ 25 сентября 2018

Простой: await it!

 public aysnc Task DownloadFromRepo(String fileName)
 {
    ...
    using (WebClient FileClient = new WebClient())
    {
        ...
        await FileClient.DownloadFileTaskAsync(new System.Uri(RepoDir + fileName), 
curFilePath);
    }
}

Без await, действительно: Dispose() происходит немедленно.

Я считаю, что рослинатор теперь автоматически обнаруживает этот сценарий ипредупреждает вас об этом (и имеет авто-исправление доступно) - его стоит установить.

Аналогично:

private async Task RetrieveUpdate()
{
    await UpdateInformationDownload.DownloadFiles();
    AnalyzeFile();
}

и:

public async Task DownloadFiles() {...}
...