0

Having had to solve the problem of iterating through the YEILDed results from a C# IAsyncEnumerable controller method myself with Javascript, by writing my own iterator to handle JSON tears, I was extolling the virtues of the C# JsonSerializer.DeserializeAsyncEnumerable method to the team as doing all the heavy lifting for us.

Then my tests show that: -

IAsyncEnumerable<SearchName?> resultNames = JsonSerializer.DeserializeAsyncEnumerable<SearchName>(outStream, opts, cancellationSource.Token);
await foreach (SearchName name in resultNames){
    Console.WriteLine(Uri.UnescapeDataString(name.familyName));
}

Won't start iterating until the entire buffer (resultNames) has been retrieved from the server and reassembled into an array by DeserializeAsyncEnumerable :-(

Do I have to write my own iterator and cater for tears in JSON chunks just like I did in Javascript?

Here at Github is a similar question. Sadly, when I follow the Bug Fix it says: -

"Fixes regression introduced by #51702: the ContinueDeserialize method will return 'null' on partial reads so no elements will be yielded by the enumerator until the entire stream has been consumed."

My question is how can I make JsonSerializer.DeserializeAsyncEnumerable (or use another C# strategy) start returning the Enumerable content Asynchronously as soon as it is available as a partial result?

dbc
  • 104,963
  • 20
  • 228
  • 340
McMurphy
  • 1,235
  • 1
  • 15
  • 39
  • Where is the stream coming from? If it's coming off `HttpResponseMessage` you need to use `HttpCompletionOption.ResponseHeadersRead` – Charlieface Jul 06 '23 at 10:25
  • The stream originates from a HttpClient: - Stream outStream = await client.GetStreamAsync(URL, cancellationToken); – McMurphy Jul 07 '23 at 01:38

1 Answers1

0

Sorry, found the answer on the next search link

TLDR; The buffer size controls the behaviour:

IAsyncEnumerable<SearchName?> resultNames = JsonSerializer.DeserializeAsyncEnumerable<SearchName>(
    outStream, 
    new JsonSerializerOptions { 
        DefaultBufferSize = 100, //** Set this value
        AllowTrailingCommas = true }, 
    cancellationSource.Token);
dbc
  • 104,963
  • 20
  • 228
  • 340
McMurphy
  • 1,235
  • 1
  • 15
  • 39