HtttpClient异步方法在第一次执行

时间:2015-12-07 14:17:02

标签: c# async-await httpclient

我注意到HttpClientSendAsyncGetStringAsync和其他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

Actualy它不会每次都抛出异常,有时它不会,在某些PC上它只能起作用(我已经在win10和win8机器上测试了它并且它工作正常好的每一次),但在Win7(在2台计算机上测试)它抛出异常...... 那么它的问题是什么?

PS在我的解决方案中,我有一些处理它的块。

更新 我已经尝试了默认的100秒,看起来它第一次连接大约14秒,接下来每个花费的时间少了一秒......

1 个答案:

答案 0 :(得分:1)

我用m_client.Timeout = new TimeSpan(15)试了一下。这意味着超时15个刻度,在接收和回答之前显然超时。

有了这个超时,我也会得到你的TaskCanceledException因此,当请求超时时,似乎会抛出异常。

我假设HttpClient.GetStringAsync使用CancellationToken启动任务,并在超时后发出该令牌的信号。内部任务抛出TaskCanceledException,因为它无法成功完成它的目的。

更新: 关于为什么第一次尝试时有时会出现问题的问题:我没有太详细的知识,但据我记忆,Windows管理进程的带宽。您可以看到,如果您在网络中复制大文件:速度会慢慢增加,但是当您启动另一个需要处理的网络时,速度会快速下降并在其他进程停止时再次缓慢恢复。因此,我不会惊讶于您首先尝试超时并在以下请求中获得结果。