HttpClient-任务已被取消-如何获取确切的错误消息?

问题描述 投票:51回答:4

我有以下测试代码。循环316934或361992次后,我总是收到“任务已取消”错误。

如果我没记错的话,有两个可能的原因导致任务被取消:a)HttpClient超时,或者b)队列中的任务过多,而某些任务超时。

我找不到有关排队任务限制的文档。我尝试创建超过500K的任务,并且没有超时。我想原因“ b”可能不正确。

Q1。还有其他原因我错过了吗?

Q2。如果是由于HttpClient超时,如何获取确切的异常消息而不是“ TaskCancellation”异常。

Q3。修复它的最佳方法是什么?我应该介绍节流阀吗?

谢谢!

var _httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");

int[] intArray = Enumerable.Range(0, 600000).ToArray();

var results = intArray                
    .Select(async t => {

        using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://www.google.com")) {
            log.Info(t);

            try {

                var response = await _httpClient.SendAsync(requestMessage);
                var responseContent = await response.Content.ReadAsStringAsync();

                return responseContent;
            }
            catch (Exception ex) {
                log.ErrorException(string.Format("SoeHtike {0}", Task.CurrentId), ex);
            }
            return null;
        }
    });

Task.WaitAll(results.ToArray());

Console.ReadLine();

这里是复制问题的步骤。

  1. 在VS 2012中创建控制台项目。

  2. 请复制我的代码并将其粘贴到Main中。

  3. 将断点放在此行“ log.ErrorException(string.Format(” SoeHtike{0}”,Task.CurrentId),例如);“

以调试模式运行程序。等待几分钟。 (也许是5分钟?)我刚刚测试了我的代码,但3分钟后我得到了异常。如果您有提琴手,则可以监视请求,以便知道程序是否仍在运行。

如果您无法复制此问题,请随时告诉我。

c# httpclient async-await
4个回答
64
投票

默认HttpClient.Timeout值为100秒(00:01:40)。如果在catch块中进行时间戳记,您会注意到任务正好在该时间开始被取消。显然,您每秒可以执行的HTTP请求数量有限,其他请求排队。排队的请求在超时时被取消。在我个人所有的600k任务中,我仅成功完成了2500个,其他任务则被取消。

我也不太可能您将能够运行全部600000个任务。许多网络驱动程序仅在很短的时间内就允许大量请求,并在一段时间后将该请求数减少到非常低的值。我的网卡只允许我在36秒内发送921个请求,并将该速度降低到每秒仅一个请求。以这种速度,将需要一周的时间才能完成所有任务。

如果您能够绕过该限制,请确保您为64位平台构建代码,因为该应用程序非常渴望内存。


34
投票

请勿处理您正在使用的HttpClient实例。很奇怪,但为我解决了这个问题。


1
投票

只是想分享我有类似的代码可以对我们的服务器进行负载测试,并且您的请求很可能超时。您可以将http请求的超时设置为max,并查看它是否对您有所更改。我尝试通过创建各种线程来访问我们的服务器。而且它增加了命中率,但最终都将超时。此外,在另一个线程上命中它们时,您也无法设置超时。


0
投票

我最近遇到了这个问题。事实证明,当我以调试模式启动Web应用程序时,启动URL使用的是https。

但是,WebApi端点的URL(在我的配置文件中)使用的是http。将其更新为使用https后,便可以调用WebApi端点。

© www.soinside.com 2019 - 2024. All rights reserved.