HttpClient异步方法在第一次执行时抛出TaskCanceledException
本文关键字:TaskCanceledException 执行 异步方法 第一次 HttpClient | 更新日期: 2023-09-27 18:26:08
我注意到HttpClient
(SendAsync
、GetStringAsync
和其他XxxAsync)的执行方法有一些奇怪的行为。我已经使用这个类登录了许多服务器并执行了它们的一些功能,我已经在循环中执行了,并注意到在执行我的应用程序后,它会等待一段时间并报告第一台服务器的故障,其他的都很好,如果重试,它会报告成功。所以我们调试了这个方法,注意到在第一次执行HttpClient.SendAsync
时,它会抛出TaskCanceledException
,实际上是TimeOutException
,因为在HttpClient中没有人抛出那个异常(一定是微软设计的某种新的编码风格)。所以我写了一些简单的例子:
public class MainClass
{
public static void Main()
{
while (true)
{
foo();
Console.ReadLine();
}
}
static async void foo()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine((await Ping()).ToString());
}
}
static async Task<bool> Ping()
{
bool result = false;
try
{
var m_HttpHandler = new HttpClientHandler()
{
UseDefaultCredentials = true,
UseCookies = false
};
HttpClient m_client = new HttpClient(m_HttpHandler);
m_client.Timeout = new TimeSpan(0, 0, 4);
var response = await m_client.GetStringAsync("http://google.com/");
result = true;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return result;
}
}
这给了我的输出
System.Threading.Tasks.TaskCanceledException: Task canceled.
in System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
in System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
in System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
in MainClass.<LogOn>d__2.MoveNext() в C:'Users'HRR'Documents'Visual Studio 201
5'Projects'ConsoleApplication1'ConsoleApplication1'Program.cs: string 35
False
True
True
True
True
True
True
True
True
True
事实上,它不会每次都抛出Exception,有时它不会,在某些PC上,它运行得很好(我在win10和win8机器上测试过它,每次都运行良好),但在Win7(在2台计算机上测试过)上,它抛出Exception。。。那么它有什么问题呢?
PS在我的解决方案中,我有一些处理它的大块。
更新我试过默认的100秒,第一次连接大约14秒,下一次每次连接的时间要短得多。。。
我用m_client.Timeout = new TimeSpan(15)
尝试过。这意味着超时15次,显然在接收和应答之前超时。
有了这个超时,我也得到了你的TaskCanceledException
所以当请求超时时,您的异常似乎被抛出了
我假设HttpClient.GetStringAsync
用CancellationToken
启动一个任务,并且它在超时后发出该令牌的信号。内部任务抛出TaskCanceledException
,因为它不能成功地完成它的目的。
更新:关于为什么有时只在第一次尝试时会出现胆小鬼的问题:我没有太详细的知识,但据我记忆所及,Windows管理进程的带宽。你可以看到,如果你在网络中复制大文件:速度会缓慢增加,但当你启动另一个需要进程的网络时,速度会快速下降,当另一个进程停止时,速度又会缓慢恢复。所以我并不感到惊讶,你在第一次尝试时会超时,并在以下请求中得到结果。