52

我有以下测试代码。循环 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), ex);"

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

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

4

4 回答 4

64

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

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

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

于 2013-10-16T15:00:16.290 回答
35

不要处置您正在使用的 HttpClient 实例。奇怪但为我解决了这个问题。

于 2014-09-15T23:00:12.920 回答
1

只是想分享一下我有一个类似的代码来负载测试我们的服务器,并且您的请求很可能超时。您可以将您的 http 请求的超时设置为最大,看看它是否对您有任何改变。我尝试通过创建各种线程来访问我们的服务器。它增加了命中,但它们最终都会超时。而且你不能在另一个线程上命中它们时设置超时。

于 2013-10-20T05:57:32.110 回答
0

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

但是,WebApi 端点的 URL(在我的配置文件中)使用的是 http。一旦我将其更新为使用 https,我就能够调用 WebApi 端点。

于 2020-04-25T18:00:21.923 回答