[英]C# exception on cancellation of background task
I have a simple HttpClient downloading solution where I need to support cancel download.我有一个简单的 HttpClient 下载解决方案,我需要支持取消下载。 Download itself works perfectly, however when I attempt to cancel download, I receive following exception:下载本身运行良好,但是当我尝试取消下载时,我收到以下异常:
Cannot access a disposed object.无法访问已处置的 object。 Object name: 'SslStream' Object 名称:'SslStream'
My code is the following:我的代码如下:
var cts = new CancellationTokenSource();
var client = new HttpClient() { Timeout = TimeSpan.FromMinutes(5) };
DownloadButton.Click += async (s, e) => {
var LocalPath = Path.Combine(AppContext.BaseDirectory, "index-5200-00.fits");
if (!File.Exists(LocalPath)) {
using (var fs = new FileStream(LocalPath, FileMode.Create, FileAccess.Write))
using (var msg = await client.GetAsync(link1, cts.Token))
await msg.Content.CopyToAsync(fs, cts.Token);
Status = "Downloaded!";
}
};
CancelButton.Click += (s, e) => {
if (!cts.IsCancellationRequested) cts.Cancel();
};
Question is, how to properly handle the download cancellation?问题是,如何正确处理下载取消?
Add a try before any async call first, then,首先在任何异步调用之前添加一个尝试,然后,
Be sure to register a callback: cancellationToken.Register(client.CancelAsync);一定要注册一个回调:cancellationToken.Register(client.CancelAsync);
then when running the method await msg.Content.CopyToAsync(fs, cts.Token);然后在运行方法时等待 msg.Content.CopyToAsync(fs, cts.Token);
On the catch block you can handle the cancelation as follows:在 catch 块上,您可以按如下方式处理取消:
catch (WebException ex) when (ex.Status == WebExceptionStatus.RequestCanceled)
{
throw new OperationCanceledException();
}
catch (TaskCanceledException)
{
throw new OperationCanceledException();
}
I ended up with this code.我最终得到了这段代码。 It works exactly as expected:它完全按预期工作:
var cts = new CancellationTokenSource();
var client = new HttpClient() { Timeout = TimeSpan.FromMinutes(5) };
DownloadButton.Click += async (s, e) => {
var LocalPath = Path.Combine(AppContext.BaseDirectory, "index-5200-00.fits");
if (!File.Exists(LocalPath)) {
try {
using (var fs = new FileStream(LocalPath, FileMode.Create, FileAccess.Write))
using (var stream = await client.GetStreamAsync(link1, cts.Token))
await stream.CopyToAsync(fs, cts.Token);
Text = "Downloaded!";
}
catch (TaskCanceledException) {
if (File.Exists(LocalPath)) File.Delete(LocalPath);
}
catch (Exception ex) {
Text = ex.Message;
}
}
};
CancelButton.Click += (s, e) => {
cts.Cancel();
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.