【发布时间】:2015-12-07 23:03:16
【问题描述】:
我注意到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
实际上它不会每次都抛出异常,有时不会,在某些 PC 上它工作正常(我已经在 win10 和 win8 机器上测试过,每次都运行良好),但在 Win7 上(经过测试在 2 台计算机上)它抛出异常...... 那么它有什么问题呢?
PS 在我的解决方案中,我有一些处理它的块。
更新 我已经尝试过默认的 100 秒,看起来它第一次连接大约 14 秒,接下来的连接花费的时间要少得多...
【问题讨论】:
-
您的代码看起来不错。我唯一能看到的是您正在为请求设置超时,在某些情况下它很可能会超时。
-
是的,但是我不明白怎么会只有第一次调用Ping()方法,为什么Win8/10的电脑上没有?
-
里面有 InnerException 吗?
-
当第一次连接需要很长时间时,是在服务器操作系统上吗?在客户端操作系统上也会发生同样的情况吗?
-
不,没有内部异常。
标签: c# async-await httpclient