取消HttpClient'POST请求
本文关键字:POST 请求 HttpClient 取消 | 更新日期: 2023-09-27 18:03:23
我正在我的Windows Phone 8应用程序上上传HttpClient.PostAsync()
的图像。用户可以选择通过UI按钮取消此上传。
为了取消POST请求,我设置了一个CancellationToken
。但这行不通。在取消请求之后,我仍然看到我的代理中正在进行上传,很明显请求被忽略了。我的代码:
using (var content = new MultipartFormDataContent())
{
var file = new StreamContent(stream);
file .Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = "filename.jpg",
};
file.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
content.Add(file);
await httpclient.PostAsync(new Uri("myurl", UriKind.Absolute), content,
cancellationToken);
}
还请注意,我有一个CancellationTokenSource
的CancellationToken
。用户单击Cancel按钮后,调用tokensource.Cancel()
。另外,我的测试用例中的图像大小从1到2 MB(不是那么大)。
所以,有没有办法取消HttpClient
POST请求?
try
{
var client = new HttpClient();
var cts = new CancellationTokenSource();
cts.CancelAfter(3000); // 3 seconds
var request = new HttpRequestMessage();
await client.PostAsync(url, content, cts.Token);
}
catch(OperationCanceledException ex)
{
// timeout has been hit
}
取消任务不会立即终止任务。您必须在执行工作之前手动检查令牌的状态:
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
// Post request here...
这篇文章非常有用:如何:取消任务及其子任务
在像Xamarin这样的Mono的HttpClient实现中,get &如果主机不可达,则post方法不执行取消令牌,并在失败之前等待最多2分钟。这可能就是为什么带有CancelAfter的CancellationTokenSource在这里不起作用的原因。
要解决这个问题,我发现最简单的方法是使用Polly库https://github.com/App-vNext/Pollyvar policy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(3000),
TimeoutStrategy.Pessimistic,
(context, timespan, task) => throw new Exception("Cannot connect to server."));
await policy.ExecuteAsync(async () =>
{
var httpClient = new HttpClient();
var response = await httpClient.PostAsync(...);
response.EnsureSuccessStatusCode();
...
});