2

Currently I am using a two step approach to fetch data from the Web Api and deserialize the CSV records into objects.

var response = await httpClient.GetAsync(queryString);
using (var reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
    var csvr = new CsvReader(reader);
    var responseValue = csvr.GetRecords<TrainingDataSetData>().ToList();
    result.Readings.AddRange(responseValue);
}

How do I optimize this code?

E. Moffat
  • 3,165
  • 1
  • 21
  • 34
jayanand
  • 47
  • 9
  • 1
    What are you trying to optimize here? Time? Memory usage? – georgevanburgh Aug 20 '18 at 10:49
  • Looks like, the code is reading the response two times. ReadAsStreamAsync and GetRecords. What I really need is var responseValue = csvr.GetRecords().ToList(); Only reason I am using the ReadAsStreamAsync is because CSVReader's StreamReader ctor arg. – jayanand Aug 20 '18 at 19:15

1 Answers1

2

If you're trying to avoid creating an intermediate MemoryStream - you could use the GetStreamAsync method on HttpClient, which should return the raw NetworkStream for you pass straight into CsvHelper, instead of ReadAsStreamAsync, which will default to reading the full response into a MemoryStream before returning.

using (var reader = new StreamReader(await httpClient.GetStreamAsync(queryString)))
{
    var csvr = new CsvReader(reader);
    var responseValue = csvr.GetRecords<TrainingDataSetData>().ToList();
    result.Readings.AddRange(responseValue);
}

If you still need access to the HttpResponseMessage, you could achieve the same effect by using HttpCompletionOption.ResponseHeadersRead, which won't buffer the response before returning.

var response = await httpClient.GetAsync(queryString, HttpCompletionOption.ResponseHeadersRead);

As to whether or not this is actually more efficient - this is something that would require benchmarking in your particular environment to decide, since it may be conditional on the size of the response, speed of the network etc.

georgevanburgh
  • 169
  • 1
  • 8