在“await DownloadTaskAsync”上调用 WebClient.Cancel

这很好用:


private WebClient _webClient;


private void ButtonStart_Click(object sender, RoutedEventArgs e) {

    using (_webClient = new WebClient()) {

        _webClient.DownloadFileTaskAsync("https://speed.hetzner.de/100MB.bin", @"D:\100MB.bin");

    }

}


private void ButtonStop_Click(object sender, RoutedEventArgs e) {

    _webClient.CancelAsync();

}

虽然此代码(注意异步/等待模式)...:


private WebClient _webClient;


private async void ButtonStart_Click(object sender, RoutedEventArgs e) {

    using (_webClient = new WebClient()) {

        await _webClient.DownloadFileTaskAsync("https://speed.hetzner.de/100MB.bin", @"D:\100MB.bin");

    }

}


private void ButtonStop_Click(object sender, RoutedEventArgs e) {

    _webClient.CancelAsync();

}

...抛出以下异常:


系统.Net.WebException


请求被中止:请求被取消。


   at System.Net.ConnectStream.EndRead(IAsyncResult asyncResult)

   at System.Net.WebClient.DownloadBitsReadCallbackState(DownloadBitsState state, IAsyncResult result)

--- End of stack trace from previous location where exception was thrown ---

   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

   at WpfApp1.MainWindow.<ButtonStart_Click>d__2.MoveNext() in WpfApp1\MainWindow.xaml.cs:line 19

如何在await WebClient.DownloadFileTaskAsync()不引发异常的情况下取消开始的任务?


PIPIONE
浏览 123回答 2
2回答

紫衣仙女

例外正是它应该如何工作。如果您不希望该异常传播出您的事件处理程序,则捕获该异常。

撒科打诨

您可以像这样捕获异常:using (_webClient = new WebClient()){&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await _webClient.DownloadFileTaskAsync("https://speed.hetzner.de/100MB.bin", @"D:\100MB.bin");&nbsp; &nbsp; }&nbsp; &nbsp; catch (WebException ex) when (ex.Status == WebExceptionStatus.RequestCanceled)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine("Cancelled");&nbsp; &nbsp; }}更新:如何更改 的默认行为CancelAsync,以避免必须捕获异常:public static Task<bool> OnCancelReturnTrue(this Task task){&nbsp; &nbsp; return task.ContinueWith(t =>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (t.IsFaulted)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (t.Exception.InnerException is WebException webEx&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && webEx.Status == WebExceptionStatus.RequestCanceled) return true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw t.Exception;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return t.IsCanceled;&nbsp; &nbsp; }, TaskContinuationOptions.ExecuteSynchronously);}使用示例:bool cancelled = await _webClient.DownloadFileTaskAsync(&nbsp; &nbsp; "https://speed.hetzner.de/100MB.bin", @"D:\100MB.bin").OnCancelReturnTrue();if (cancelled) Console.WriteLine("Cancelled");
打开App,查看更多内容
随时随地看视频慕课网APP