C# HttpClient-任务已取消-如何获取确切的错误消息?
我有以下测试代码。我总是在循环316934或361992次后出现“任务被取消”错误 如果我没有错的话,有两个可能的原因导致任务被取消a)HttpClient超时或b)队列中的任务太多,一些任务超时 我找不到关于任务排队限制的文档。我尝试创建超过500K的任务,并且没有超时。我想“b”的原因可能不对 问题1。还有其他原因让我错过了吗 问题2。如果是因为HttpClient超时,我如何获得确切的异常消息而不是“TaskCancellation”异常 第三季度。最好的解决方法是什么?我应该介绍节流阀吗 谢谢C# HttpClient-任务已取消-如何获取确切的错误消息?,c#,httpclient,async-await,C#,Httpclient,Async Await,我有以下测试代码。我总是在循环316934或361992次后出现“任务被取消”错误 如果我没有错的话,有两个可能的原因导致任务被取消a)HttpClient超时或b)队列中的任务太多,一些任务超时 我找不到关于任务排队限制的文档。我尝试创建超过500K的任务,并且没有超时。我想“b”的原因可能不对 问题1。还有其他原因让我错过了吗 问题2。如果是因为HttpClient超时,我如何获得确切的异常消息而不是“TaskCancellation”异常 第三季度。最好的解决方法是什么?我应该介绍节流阀吗
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();
下面是复制问题的步骤
如果您无法复制此问题,请随时通知我 默认的
HttpClient.Timeout
值为100秒(00:01:40)。如果在catch
块中设置时间戳,您会注意到任务正是在这个时间开始被取消的。显然,您每秒可以执行的HTTP请求数量是有限的,其他请求会排队。排队的请求在超时时被取消。在我个人完成的所有60万项任务中,只有2500项成功,其他任务则被取消
我还发现,您不太可能运行整个600000个任务。许多网络驱动程序只在很短的时间内允许大量请求通过,并在一段时间后将该数量减少到非常低的值。我的网卡允许我在36秒内只发送921个请求,并将该速度降至每秒仅发送一个请求。以这种速度完成所有任务需要一周的时间
如果您能够绕过该限制,请确保为64位平台构建代码,因为该应用程序非常需要内存。只是想与大家分享
我有一个类似的代码来对我们的服务器进行负载测试,您的请求很可能超时。
您可以将http请求的超时设置为max,并查看它是否为您更改了任何内容。
我尝试通过创建各种线程来访问我们的服务器。它增加了命中率,但它们最终都会超时。而且,当在另一个线程上命中它们时,您不能设置超时。不要处理您正在使用的HttpClient实例。奇怪,但我解决了这个问题。我最近遇到了这个问题。事实证明,当我在调试模式下启动web应用程序时,启动URL使用的是https
但是,WebApi端点的URL(在我的配置文件中)使用http。一旦我将其更新为使用https,我就能够调用WebApi端点。你所做的是让页面600.000它实际上是一种DOS攻击,你不应该这样做。嗨,我明白了。但也有一些网站可以处理巨大的请求。我真的很想知道为什么我得到了“任务被取消”而没有实际的错误消息。而且,我不认为这是阻止我的网站request@Pedro.The.Kid也许他是在粗暴地强迫自己的网站建立防御DOS攻击的保护?我只是创建了一个控制台应用程序,向API发送大量请求,以模拟“真实”的这是唯一对我有用的东西。当然很奇怪。哇,我一直在为这个发疯,而且。。。你的是唯一修复它的东西。与@jpgrassi做的差不多。这并不奇怪,解释了为什么以及如何使用
HttpClient
。如果您感兴趣,您还可以检查类的CIL,看看为什么不应该自己频繁地处理它。@Sergey.quixoticaxis.Ivanov:本文的代码示例说(原文如此):“//使用HttpClient对象时需要调用dispose,这样应用程序就不会泄漏资源”。另外,一种普遍接受的模式是处理实现IDisposable的所有内容。@abatishchevHttpClient旨在实例化一次,并在应用程序的整个生命周期中重复使用。为每个请求实例化HttpClient类将耗尽重载下可用的套接字数量。这将导致SocketException错误
您的选择,但遵循这种广为接受的模式通常会使代码变得缓慢、难看甚至不可靠(通常情况下,以及遇到像HttpClient
这样的类时,这些类100%不打算以这种方式使用)。您好,请在回答中详细说明。我也遇到了同样的问题。如何确定我的应用程序中运行了多少任务?超时。谢谢,这就是我要找的。