指定超时之前的HttpClient超时

时间:2014-04-18 00:16:54

标签: windows-phone-8 timeout dotnet-httpclient

我正在使用WP8中的HttpClient并执行Post请求。我知道这个电话可能需要很长时间,因为我实际上正在模拟慢速网络场景。因此,我将HttpClient.Timeout相应地设置为5分钟。

然而,我在60秒左右得到超时。我相信超时不起作用。 我认为这个问题对于WP来说存在问题: HttpClient Portable returns 404 notfound on WP8

他们使用变通方法,但这不适用于我的方案。我确实想等很长时间。

我的问题:

1)这是WP8的HttpClient的错误/问题,还是我没有正确设置? 2)您是否考虑过仍在使用HttpClient的变通方法?

我读过可能HttpWebRequest是一个选项。但是,我相信HttpClient应该是这个简单'场景。

我的代码很简单:

private static async Task<HttpResponseMessage> PostAsync(Uri serverUri, HttpContent httpContent)
{
    var client = new HttpClient();
    client.Timeout = TimeSpan.FromMinutes(5);
    return await client.PostAsync(serverUri, httpContent).ConfigureAwait(false);
}

服务器收到请求,在处理请求时,客户端将中止。

更新:HttpResponseMessage返回的HttpClient.PostAsyn"{StatusCode: 404, ReasonPhrase: '', Version: 0.0, Content: System.Net.Http.StreamContent, Headers: { Content-Length: 0 }}"。正如我所说,服务器已找到并正在接收数据并进行处理。

2 个答案:

答案 0 :(得分:1)

经过一些搜索和一些测试后,我得出结论,问题是Windows Phone本身,并且它有60秒超时(无论HttpClient如何),并且根据我的知识无法改变。请参阅http://social.msdn.microsoft.com/Forums/en-US/faf00a04-8a2e-4a64-b1c1-74c52cf685d3/httpwebrequest-60-seconds-timeout

当我正在为服务器编程时,我将尝试Darin Rousseau在上面提供的链接中的建议,特别是发送一个OK然后再做一些处理。


更新:问题似乎是Windows Phone模拟器,如下所述: http://social.msdn.microsoft.com/forums/wpapps/en-us/6c114ae9-4dc1-4e1f-afb2-a6b9004bf0c6/httpclient-doesnt-work-on-windows-phone?forum=wpdevelop。根据我的经验,如果60秒没有听到任何声音,tcp连接会超时。


因此我的解决方案是使用Http标题字符作为一种保持活力的方式。第一行Http标头响应始终以HTTP/1.0开头。所以我逐个发送字符,延迟时间<60秒。当然,如果响应准备就绪,剩下的所有内容都会立即发送。这需要一些时间,例如,如果每9个字符使用50秒的延迟,我们会得到大约450秒。

这是我的学位课程,所以我不建议将其用于制作。

顺便说一下,我也尝试用其他字符代替标题的子字符串,例如空格字符,但这会导致http协议违规。

这是代码的主要部分:

    private const string Header1 = @"HTTP/1.0 ";
    private int _keepAliveCounter = 0;
    private readonly object _sendingLock = new object();
    private bool _keepAliveDone = true;

    private void StartKeepAlive()
    {
        Task.Run(() => KeepAlive());
    }

    /// <summary>
    /// Keeps the connection alive sending the first characters of the http response with an interval.
    /// This is a hack for Windows Phone 8 that need reponses within 60s interval.
    /// </summary>
    private void KeepAlive()
    {
        try
        {
            _keepAliveDone = false;
            _keepAliveCounter = 0;
            while (!_keepAliveDone && _keepAliveCounter < Header1.Length)
            {
                Task.Delay(TimeSpan.FromSeconds(50)).Wait();
                lock (_sendingLock)
                {
                    if (!_keepAliveDone)
                    {
                        var sw = new StreamWriter(OutputStream);
                        sw.Write(Header1[_keepAliveCounter]);
                        Console.Out.WriteLine("Wrote keep alive char '{0}'", Header1[_keepAliveCounter]);
                        _keepAliveCounter++;
                        sw.Flush();
                    }
                }
            }
            _keepAliveCounter = 0;
             _keepAliveDone = true;
        }
        catch (Exception e)
        {
            // log the exception
            Console.Out.WriteLine("Error while sending keepalive: " + e.Message);
        }
    }

然后,实际处理发生在另一个线程中。

赞赏评论和评论家。

答案 1 :(得分:0)

您可能正在达到网络流的超时。您可以通过执行此操作来更改

var handler = new WebRequestHandler();
handler.ReadWriteTimeout= 5 * 60 * 1000;
var client = new HttpClient(handler);
client.Timeout = TimeSpan.FromMinutes(5);
return await client.PostAsync(serverUri, httpContent).ConfigureAwait(false);

桌面操作系统的默认值已经是5分钟。但是,有可能在Windows Phone上默认情况下已经减少了。