HttpClient with infinite time out throws time out exception

后端 未结 3 1308
被撕碎了的回忆
被撕碎了的回忆 2021-02-15 18:13

My HttpClient uses digest authentication to connect to the server and expects search queries in response. These search queries can come in any time so the client is expected to

相关标签:
3条回答
  • 2021-02-15 18:41

    Although the default value for Stream.CanTimeout is false, returning a stream via the response.Content.ReadAsStreamAsync() gives a stream where the CanTimeout property returns true.

    The default read and write time out for this stream is 5 minutes. That is after five minutes of inactivity, the stream will throw an exception. Much similar to the exception shown in the question.

    To change this behavior, ReadTimeout and/or the WriteTimeout property of the stream can be adjusted.

    Below is the modified version of the ListenForSearchQueries method that changes the ReadTimeout to Infinite.

    public static async void ListenForSearchQueries(int resourceId)
    {
        var url = $"xxx/yyy/{resourceId}/waitForSearchRequest?token=abc";
    
        var httpHandler = new HttpClientHandler { PreAuthenticate = true };
    
        using (var digestAuthMessageHandler = new DigestAuthMessageHandler(httpHandler, "user", "password"))
        using (var client = new HttpClient(digestAuthMessageHandler))
        {
            client.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
    
            var request = new HttpRequestMessage(HttpMethod.Get, url);
    
            var tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(TimeSpan.FromMilliseconds(Timeout.Infinite));
    
            using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, tokenSource.Token))
            {
                Console.WriteLine("\nResponse code: " + response.StatusCode);
    
                using (var body = await response.Content.ReadAsStreamAsync())
                {
                    body.ReadTimeout = Timeout.Infinite;
    
                    using (var reader = new StreamReader(body))
                        while (!reader.EndOfStream)
                            Console.WriteLine(reader.ReadLine());
                }
             }
        }
    }
    

    This fixed the exception which was actually being thrown by the stream but seemed like was being thrown by the HttpClient.

    0 讨论(0)
  • 2021-02-15 19:00

    I solved this problem in the following way:

    var stream = await response.Content.ReadAsStreamAsync();
        while (b == 1)
        { 
            var bytes = new byte[1];
            try
            {
                var bytesread = await stream.ReadAsync(bytes, 0, 1);
                if (bytesread > 0)
                {
                    text = Encoding.UTF8.GetString(bytes);
    
                    Console.WriteLine(text);
                    using (System.IO.StreamWriter escritor = new System.IO.StreamWriter(@"C:\orden\ConSegu.txt", true))
                    {
                        if (ctext == 100)
                        {
                            escritor.WriteLine(text);
                            ctext = 0;
                        }
                        escritor.Write(text);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("error");
                Console.WriteLine(ex.Message);
            }
        }
    

    in this way I get byte to byte the answer and I save it in a txt later I read the txt and I'm erasing it again. for the moment it is the solution I found to receive the notifications sent to me by the server from the persistent HTTP connection.

    0 讨论(0)
  • 2021-02-15 19:02

    Make the method return a Task

    public static async Task ListenForSearchQueries(int resourceId) {
        //...code removed for brevity
    }
    

    Update the console's main method to Wait on the Task to complete.

    public static void Main(string[] args) {
       const int serviceId = 128;
       .
       .
       .
       ListenForSearchQueries(resourceId).Wait();
       Console.ReadKey();
    }
    
    0 讨论(0)
提交回复
热议问题