C# 在上取消了临时任务。HttpClient代码的结果

C# 在上取消了临时任务。HttpClient代码的结果,c#,multithreading,async-await,C#,Multithreading,Async Await,我对此有点困惑。在下面的代码中,我偶尔会遇到一个被取消的任务异常。这并不是因为它超时了——它发生得太快了 假设下面代码中的MakeRequest生成URL,并返回 return await _client.SendAsync(request, cancellationToken).ConfigureAwait(false); 代码的其余部分获取响应并确保其成功,否则抛出 protected async Task<T> MakeRequestAndResponseAsync&

我对此有点困惑。在下面的代码中,我偶尔会遇到一个被取消的任务异常。这并不是因为它超时了——它发生得太快了

假设下面代码中的MakeRequest生成URL,并返回

return await _client.SendAsync(request, cancellationToken).ConfigureAwait(false);
代码的其余部分获取响应并确保其成功,否则抛出

    protected async Task<T> MakeRequestAndResponseAsync<T>(
        HttpRequestMessage request,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var response = await MakeRequest(request, cancellationToken).ConfigureAwait(false);
        return await GetResponse<T>(response, throwsOnNotFound).ConfigureAwait(false);
    }

    protected async Task<T> GetResponse<T>(HttpResponseMessage response, Boolean throwsOnNotFound = true)
    {
        String content = await EnsureSuccessfulResponse(response, throwsOnNotFound).ConfigureAwait(false);
        if (content == null && !throwsOnNotFound) return default(T);
        return JsonConvert.DeserializeObject<T>(content);
    }

    protected async Task<String> EnsureSuccessfulResponse(HttpResponseMessage response, Boolean throwsOnNotFound = true)
    {
        String content = string.Empty;
        if (response.Content != null)
        {
            content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }

        if (response.IsSuccessStatusCode) return content;

        var error = JsonConvert.DeserializeObject<ApiErrorResponse>(content);
        throw new ApiErrorException(/*some internal stuff*/);
    }
到目前为止,我已经划掉了:

  • HttpClient已正确初始化并重新使用。它不会中途被处理掉
  • 这种错误有时会发生。这些请求是并行的,所以我认为HttpClient SendAsync不是线程安全的,但我发现实际上它是线程安全的
  • 这不是超时异常。每个请求我都有一个唯一的id,我可以在日志中看到它何时启动以及何时出错(大约1-2秒)
我不知道的是: -如果另一个服务返回非200,我会故意抛出一个自定义异常(ApiErrorException)。我怀疑这可能与此有关,即任务在抛出时被取消。如果是这样的话,我希望返回ApiErrorException,而不是task cancelled异常。我打开所有内部异常,直到一无所有。剩下的是TaskCancelled异常

任何帮助都将不胜感激


谢谢

您是否检查了所获得异常的属性?@Yannis-有多少线程同时执行此操作?他们是否共享一个
HttpClient
?正如您所指出的,
HttpClient
是线程安全的,但是
HttpWebRequest
使用的默认限制是每个主机有两个并发连接。也许许多线程不得不等待。我不确定等待是否会导致超时,但可能值得调查。这是5个线程。@PauloMorgado不幸的是,我无法在本地复制它。它只发生在请求量大得多的生产环境中。@Yannis-您能在日志中看到
TaskCanceledException.CancellationToken.IsCancellationRequested
的值吗,它的值是什么?你检查过你得到的异常的属性了吗?@Yannis-有多少线程同时执行这个操作?他们是否共享一个
HttpClient
?正如您所指出的,
HttpClient
是线程安全的,但是
HttpWebRequest
使用的默认限制是每个主机有两个并发连接。也许许多线程不得不等待。我不确定等待是否会导致超时,但可能值得调查。这是5个线程。@PauloMorgado不幸的是,我无法在本地复制它。它只发生在请求量大得多的生产环境中。@Yannis-您能在日志中看到
TaskCanceledException.CancellationToken.IsCancellationRequested
的值吗?如果是,它的值是多少?
var result = MakeRequestAndResponseAsync(...).Result;
// do something with result