c# - HttpClient 与 HttpClientHandler 取消不起作用

Γαβ*_*λης 6 c# httpclient xamarin.forms

我正面临 HttpClient(.NETStandard v2.1,System.Net.Http,针对单声道运行时)的问题。我想通过在 SendAsync 中传递取消令牌来为每个请求设置 HttpClient 超时。它在使用 HttpClient 的无参数构造函数时正常工作,但在将 HttpClientHandler 的实例传递给 HttpClient 协构造函数时会被忽略。75 秒后取消操作。

为了显示:

public static async Task<HttpResponseMessage> Send()
{
    var req = new HttpRequestMessage(HttpMethod.Get, new 
            Uri("someURL"));
    var handler= new HttpClientHandler{CookieContainer = new 
            CookieContainer()};  
    /*var client = new HttpClient(); <--- This is working */          
    var client = new HttpClient(handler);
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
    cts.Token.Register(() => Debug.WriteLine("TASK CANCELLED"));
    return await client.SendAsync(req, cts.Token);
}
Run Code Online (Sandbox Code Playgroud)

5 秒后,调试输出写入“TASK CANCELLED”,但 SendAsync 总共持续了 75 秒。如果我使用无参数构造函数,SendAsync 会在 5 秒后取消。

我需要 HttpClientHandler 来使用 CookieContainer 属性。我在这里缺少什么?

编辑

经过进一步调查和@Lasse Vågsæther Karlsen 的提示后,我得出以下结论:

  1. .NET Core 3 运行时

    • 如果无法访问 url 或 Internet 连接中断,则 HttpClient 在 3 秒后抛出 HttpRequestException
    • 否则它会在 5 秒后按预期取消
  2. Mono 运行时(Xamarin.Forms 项目)

    • 如果无法访问 url 或 Internet 连接中断,则 HttpClient 在 75 秒后抛出 OperationCanceledException
    • 否则它会在 5 秒后按预期取消

也许它与这个https://forums.xamarin.com/discussion/5941/system-net-http-httpclient-timeout-seems-to-be-ignored 有关

虽然仍然是一个悬而未决的问题......

Har*_*dis 1

我发现的最简单的方法是使用Polly 库并包装不遵守CancellationToken. 你甚至不需要一个CancellationToken. 例子:

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();
    ...
});
Run Code Online (Sandbox Code Playgroud)