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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19120675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:09:05  来源:igfitidea点击:

HttpClient - task was cancelled - How to get the exact error message?

c#httpclientasync-await

提问by Michael Sync

I have the following test code. I always get the "Task was cancelled" error after looping 316934 or 361992 times.

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

If I am not wrong, there are two possible reasons why the task was cancelled a) HttpClient got timeout or b) too many tasks in queue and some tasks got time-out.

如果我没记错的话,任务被取消的可能原因有两个 a) HttpClient 超时或 b) 队列中的任务太多并且某些任务超时。

I couldn't find the documentation about the limitation in queueing the tasks. And I tried creating more than 500K tasks and no time-out. I guess the reason "b" might not be right.

我找不到有关排队任务限制的文档。我尝试创建超过 50 万个任务并且没有超时。我想原因“b”可能不对。

Q1. Is there any other reason that I missed out?

一季度。有没有其他原因我错过了?

Q2. If it's because HttpClient timeout, how can I get the exact exception message instead of "TaskCancellation" exception.

Q2。如果是因为 HttpClient 超时,我怎样才能获得确切的异常消息而不是“TaskCancellation”异常。

Q3. What would be the best way to fix it? Should I introduce the throttler?

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

Thanks!

谢谢!

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();

Here is the step to replicate the issue.

这是复制问题的步骤。

  1. Create a Console Project in VS 2012.

  2. Please copy and paste my code in Main.

  3. Put the breakpoint at this line " log.ErrorException(string.Format("SoeHtike {0}", Task.CurrentId), ex);"

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

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

  3. 将断点放在这一行“ log.ErrorException(string.Format("SoeHtike {0}", Task.CurrentId), ex);”

Run the program in debug mode. Wait for a few minutes. (maybe 5 minutes? ) I just tested my code and I got the exception after 3 mins. If you have fiddler, you can monitor the requests so that you know the program is still running or not.

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

Feel free to let me know if you can't replicate the issue.

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

采纳答案by Dmitri Trofimov

The default HttpClient.Timeoutvalue is 100 seconds (00:01:40). If you do a timestamp in your catchblock you will notice that tasks begin to get canceled at exactly that time. Apparently there is a limited number of HTTP requests you can do per second, others get queued. Queued requests get canceled on timeout. Out of all 600k of tasks I personally got only 2500 successful, others got canceled.

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

I also find it unlikely, that you will be able to run the whole 600000 of tasks. Many network drivers let through high number of requests only for a small time, and reduce that number to a very low value after some time. My network card allowed me to send only 921 requests within 36 seconds and dropped that speed to only one request per second. At that speed it will take a week to complete all the tasks.

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

If you are able to bypass that limitation, make sure you build the code for 64-bit platform as the app is very hungry for memory.

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

回答by Andy Khatter

just wanted to share I have had a similar code to load test our servers ,and its a high probability that your requests are timing out. You can set the timeout for your http request to max and see if it changes anything for you. I tried hitting our servers by creating various threads. And it increased the hits but they would all eventually timeout.And also you cannot set a timeout when hitting them on another thread.

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

回答by abatishchev

Don't dispose the instance of HttpClient you're using. Weird but fixed for me this problem.

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

回答by Carl Prothman

I ran across this recently. As it turned out, when I started up the web application in debug mode, the start up URL was using https.

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

However, the URL for WebApi endpoint (in my config file) was using http. Once I update it to use https, I was able to call the WebApi endpoint.

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