HttpClient代码的.Result取消偶尔的任务

时间:2016-12-18 19:43:40

标签: c# multithreading async-await

我对此有点疑惑。我在下面的代码中偶尔会取消任务取消异常。这不是因为它超时 - 它发生得太快了。

假设下面代码中的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*/);
    }

从这样的控制台应用程序调用整个代码。这是一个多线程应用程序,因此可以同时多次调用此代码。

var result = MakeRequestAndResponseAsync(...).Result;
// do something with result

到目前为止我已经划掉了:

  • HttpClient已正确初始化并重新使用。它不会中途处理。
  • 有时会发生此错误。这些请求是并行发生的,所以我认为HttpClient SendAsync不是线程安全的,但我发现here实际上它是线程安全的
  • 它不是超时异常。我每个请求都有一个唯一的ID,我可以在日志中看到它启动时和错误时间(大约1-2秒)

我不知道的事: - 如果其他服务返回非200我故意抛出自定义异常(ApiErrorException)。我怀疑它可能与此有关,即任务在抛出时被取消。如果是这种情况我会期望得到ApiErrorException而不是任务取消异常。我解开了所有内在的例外,以至于没有任何东西可以留下。剩下的是TaskCancelled异常。

非常感谢任何帮助。

由于

0 个答案:

没有答案