Home > Enterprise >  Read asynchronously each line of an HTTP request
Read asynchronously each line of an HTTP request

Time:07-10

I use a strange API that sends JSON objects in kind of chunks (line by line).

I need to be able to read each line of the response to my request asynchronously. I'm already trying to display in the console each of these requests.

The code below is the main one (the main{} function only calls this function). I want this code to be executed asynchronously too, that's why the function is declared as async task.

When I launch the application, the query runs fine, but the program doesn't display the lines one by one: it waits for the end of the query to display everything at once.

I'm very new to async/streams, sorry if the code is so bad.

    public async Task test()
    {
        HttpClient client = new HttpClient();
        var values = new Dictionary<string, string> // POST data
            {
                { "api", "v2" },
                { "field1", "data1" },
                { "field2", "data2" }
            };
        var content = new FormUrlEncodedContent(values);
        var response = await client.PostAsync("http://api.domain/post", content);
        using (var theStream = await response.Content.ReadAsStreamAsync())
        {
            StreamReader theStreamReader = new StreamReader(theStream);
            string theLine = null;
    
            while ((theLine = await theStreamReader.ReadLineAsync()) != null)
            {
                Console.WriteLine("----- New Line:"); //Just for the eyes
                Console.WriteLine(theLine);
            }
        };
    }

CodePudding user response:

You are missing HttpCompletionOption.ResponseHeadersRead, which will only block while reading the headers, and the content comes through asynchronously. You must use SendAsync and a HttpRequestMessage for this.

Also you are missing some using blocks, and HttpClient should be cached in a static field.

 static HttpClient _client = new HttpClient();

 public async Task test()
 {
     var values = new Dictionary<string, string> // POST data
         {
             { "api", "v2" },
             { "field1", "data1" },
             { "field2", "data2" }
         };
     using (var content = new FormUrlEncodedContent(values))
     using (var request = new HttpRequestMessage(HttpMethod.Post, "http://api.domain/post"){ Content = content })
     using (var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
     using (var theStream = await response.Content.ReadAsStreamAsync())
     using (var theStreamReader = new StreamReader(theStream))
     {
         string theLine = null;
 
         while ((theLine = await theStreamReader.ReadLineAsync()) != null)
         {
             Console.WriteLine("----- New Line:"); //Just for the eyes
             Console.WriteLine(theLine);
         }
     };
 }
  • Related