的任务.等等,不像我想象的那样起作用

本文关键字:起作用 任务 等等 | 更新日期: 2023-09-27 18:19:04

我正在尝试下载文件,等待文件下载完成,然后再读取文件。我有以下方法来做到这一点:

private async Task startDownload(string link, string savePath)
{      
        WebClient client = new WebClient();
        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
        client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
        await client.DownloadFileTaskAsync(new Uri(link), savePath);              
}
private void checkUpdateButton_Click(object sender, EventArgs e)
{           
    Task task = Task.Factory.StartNew(() => startDownload(versionLink, versionSaveTo));
    task.Wait();
    if (task.IsCompleted)
    {
        checkVersion();
    }
}

checkVersion()方法读取下载的文件。这会抛出一个IOException,表示文件正在被其他东西使用,无法读取。我认为有task.Wait会阻止该方法的其余部分执行,直到任务完成?

的任务.等等,不像我想象的那样起作用

Task.Wait将阻塞当前线程(在本例中为UI线程)并等待任务完成。在本例中,任务完成时出现错误,因此Task.Wait将抛出该错误,并将其封装在AggregateException中。

正如其他人所指出的,您应该使用await而不是Wait。此外,DownloadFileCompleted没有意义,因为你正在使用DownloadFileTaskAsync(而不是DownloadFileAsync);和StartNew是不需要的,因为下载是异步的。

哦,让我们处理WebClient,并确保我们的命名约定遵循基于任务的异步模式。

private async Task startDownloadAsync(string link, string savePath)
{      
  using (var client = new WebClient())
  {
    client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
    await client.DownloadFileTaskAsync(new Uri(link), savePath);              
  }
}
private async void checkUpdateButton_Click(object sender, EventArgs e)
{           
  await startDownloadAsync(versionLink, versionSaveTo);
  checkVersion();
}

函数startDownload已经是异步的,所以它将启动Task并立即返回。在调用checkVersion()之前,您可以使用ContinueWith来确保任务已经完成。

    private void checkUpdateButton_Click(object sender, EventArgs e)
    {
        var task = startDownload(versionLink, versionSaveTo);
        task.ContinueWith((x) => checkVersion());
    }

正如Servy指出的那样,另一种选择是在Click事件中使用async/await。

    private async void checkUpdateButton_Click(object sender, EventArgs e)
    {
        await startDownload(versionLink, versionSaveTo);
        checkVersion();
    }

你需要等待你的Task.Factory.StartNew(...)调用,这样它就不会阻塞UI线程。

private async void button1_Click(object sender, EventArgs e)
{
    Task task = await Task.Factory.StartNew(() => startDownload("http://www.zwaldtransport.com/images/placeholders/placeholder1.jpg", "" + "sd.jpg"));
}
private async Task startDownload(string link, string savePath)
{
    WebClient client = new WebClient();
    client.DownloadProgressChanged += Client_DownloadProgressChanged;
    client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
    await client.DownloadFileTaskAsync(new Uri(link), savePath);
}
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
            checkVersion();
    Console.WriteLine("Done, unless error or cancelled.");
}
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("Progress changed.");
}

图片占位符来自Google Images和其他一些网站。