简体   繁体   English

取消 'HttpClient' POST 请求

[英]Cancel an 'HttpClient' POST request

I am uploading an image with HttpClient.PostAsync() on my Windows Phone 8 app.我正在我的 Windows Phone 8 应用程序上使用HttpClient.PostAsync()上传图像。 The user has the option to cancel this upload via a UI button.用户可以选择通过 UI 按钮取消此上传。

To cancel the POST request, I set a CancellationToken .要取消 POST 请求,我设置了CancellationToken But this doesn't work.但这不起作用。 After the cancellation request, I see still see the upload taking place in my proxy and it is evident that the request was ignored.在取消请求之后,我仍然看到在我的代理中进行上传,很明显请求被忽略了。 My code:我的代码:

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

Please also note that I have a CancellationTokenSource for the CancellationToken .另请注意,我有CancellationTokenSourceCancellationToken After the user clicks on the Cancel button, tokensource.Cancel() is called.用户单击取消按钮后,将调用tokensource.Cancel() Also, the images in my testcase are from 1 to 2 MB (not that big).此外,我的测试用例中的图像从 1 到 2 MB(不是那么大)。

So, is there a way to cancel an HttpClient POST request?那么,有没有办法取消HttpClient POST 请求?

   try
   {
          var client = new HttpClient();

          var cts = new CancellationTokenSource();
          cts.CancelAfter(3000); // 3seconds

          var request = new HttpRequestMessage();

          await client.PostAsync(url, content, cts.Token);

  }
  catch(OperationCanceledException ex)
  {
          // timeout has been hit
  }

Cancelling a task doesn't terminate it instantly.取消任务不会立即终止它。 You have to check manually before doing your work by checking the token's status:在进行工作之前,您必须通过检查令牌的状态进行手动检查:

if (ct.IsCancellationRequested) 
{
    ct.ThrowIfCancellationRequested();
}

// Post request here...

This article is quite useful: How to: Cancel a Task and Its Children这篇文章非常有用: 如何:取消任务及其子项

In implementations of HttpClient for Mono like in Xamarin, the get & post methods don't honor the cancellation token if the host is not reachable , and wait up to 2 minutes before failing.在 Xamarin 中的 Mono 的 HttpClient 实现中,如果主机不可访问,get 和 post 方法不遵守取消令牌,并在失败前等待最多 2 分钟。 This is perhaps why CancellationTokenSource with a CancelAfter does not work here.这也许就是为什么带有 CancelAfter 的 CancellationTokenSource 在这里不起作用的原因。

To fix this, the simplest method I found was using the Polly library https://github.com/App-vNext/Polly为了解决这个问题,我发现最简单的方法是使用 Polly 库https://github.com/App-vNext/Polly

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM