异步/任务/等待:等待实际上并不等待

时间:2018-09-25 14:45:12

标签: c# asynchronous async-await task webclient

我正在实现一种方法,以便互相下载多个文件。

我希望方法是异步的,所以我不会阻止UI。

这是下载单个文件并将下载任务返回到高级方法的方法,该方法将下载所有文件(进一步下载)。

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);
            }
        }

在这里,我只是根据FilesToDownload中的所有文件创建一个IEnumerable<Task>

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(),然后尝试访问当前正在下载的文件。

需要我希望能够呼叫UpdateInformationDownload.DownloadFiles(),等待它完成(这意味着它下载了所有文件),然后继续与AnalyzeFile()同步。

我该如何实现?我已经在Internet上查找了大量资源,并找到了一些解释和Microsoft Docs,但是我认为我没有逐步完成使用async / await的方案。

1 个答案:

答案 0 :(得分:7)

简单:await

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

在没有await的情况下,实际上:Dispose()立即发生。

我相信roslynator现在会自动检测到这种情况并警告您(并提供了自动修复功能),非常值得安装。

类似:

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

和:

public async Task DownloadFiles() {...}