无休止的Http流超时

时间:2017-04-20 20:24:53

标签: c# timeout http-streaming

我正在编写用于REST服务的C#客户端来访问Http流API。我应该打开流并接收服务器无休止地发送的消息。从外部命令读取流应该停止。 HttpClient用于实现。变量streamingActive用于停止从流中读取,因为reader.EndOfStream永远不会返回值true。

using (HttpClient httpClient = new HttpClient())
{
    httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
    var messagesUri = "http://127.0.0.1:8080/api/messages/progress?sender_id=7837492342";
    var stream = httpClient.GetStreamAsync(messagesUri).Result;

    using (var reader = new StreamReader(stream))
    {
        while (streamingActive && !reader.EndOfStream)
        {
            var currentLine = reader.ReadLine();
            try
            {
                var psMessage = JsonConvert.DeserializeObject<PSMessage>(currentLine);
                Console.WriteLine(psMessage);
            }
            catch (JsonReaderException exc)
            {}
        }
    }
}

当有来自服务器的消息时,它工作正常。如果没有来自服务器的新消息〜300秒,则调用reader.EndOfStream抛出异常“操作已经超时。”

at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 count)

有没有办法让流永远打开(假设)?

1 个答案:

答案 0 :(得分:0)

如果您愿意放弃StreamReader,为什么不直接打开Stream对象?以下是通用应用程序(使用Windows.Web API)

HttpResponseMessage respMessage;
//note: client and request is defined elsewhere.
respMessage = client.SendRequestAsync(request, HttpCompletionOption.ResponseHeadersRead);
using (var responseStream = await respMessage.Content.ReadAsInputStreamAsync())
{
   using (var fileWriteStream = await fileToStore.OpenAsync(FileAccessMode.ReadWrite))
     {
        while (streamingActive && (await responseStream.ReadAsync(streamReadBuffer, bufferLength, InputStreamOptions.None)).Length > 0)
        {
          await fileWriteStream.WriteAsync(streamReadBuffer);
       }
     }
}

这应该无限期地等待await responseStream.ReadAsync。如果您仍然需要取消操作,则可以使用Task CancellationToken方法。