Task.wait不工作我想象(Task.wait not working as I imagine

2019-10-20 18:39发布

我试图下载一个文件,等待文件完成下载,然后再读取该文件之后。 我有以下的方法来做到这一点:

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会阻止执行,直到任务的方法的其余完成了吗?

Answer 1:

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


Answer 2:

该功能startDownload已经是异步,所以这将启动任务并立即返回。 您可以使用ContinueWith确保任务调用checkVersion之前完成()。

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

另一种,如Servy指出,将使用异步/等待Click事件中。

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


Answer 3:

你需要等待你的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.");
}

图像占位符礼貌谷歌图片和其他一些网站。



文章来源: Task.wait not working as I imagined