Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

System.Text.Json asynchronous streaming deserialization support #29906

Closed
mqudsi opened this issue Jun 16, 2019 · 3 comments
Closed

System.Text.Json asynchronous streaming deserialization support #29906

mqudsi opened this issue Jun 16, 2019 · 3 comments
Labels
area-System.Text.Json json-functionality-doc Missing JSON specific functionality that needs documenting
Milestone

Comments

@mqudsi
Copy link

mqudsi commented Jun 16, 2019

Hello team,

We've been eager to try the new System.Text.Json APIs for their native UTF8 support, but it seems based off the preview release announcement and the API exposed by the current preview release of the System.Text.Json that there's a lack of streaming support, i.e. reading individual JSON tokens without first having the entire document loaded into memory (and then parsed as a JsonDocument).

The Newtonsoft JSON library had a JsonTextReader that could lazily consume an underlying Stream and return a token at a time via JsonTextReader.ReadAsync(..), which moved the document cursor/pointer to the next node in the stream. It had some shortcomings (it couldn't skip past a nested node, you had to step through it IIRC) but it served the purpose of being able to navigate asynchronously to a particular node in a JSON document and then selectively parse its value without having to first buffer the entire stream beforehand or to parse the entirety of the document in order to enumerate its nodes.

I assumed that Utf8JsonReader would for sure do the same thing, but it seems that a Utf8JsonReader can only be created on top of an available ReadOnlySequence<T> and all its methods are blocking. JsonDocument can be created on top of a Stream and does not appear to consume the entire stream upon initialization, but only offers a ParseAsync() method that asynchronously reads from the underlying stream; except it consumes the entirety of the stream and loads the entire document into memory.

I'm probably missing something, but is there no way to asynchronously and lazily navigate a UTF8 JSON stream, without buffering the entire document in memory and without blocking unnecessarily for IO?

@mqudsi
Copy link
Author

mqudsi commented Jun 16, 2019

I see now that Utf8JsonReader is re-entrant and so an asynchronous wrapper around Utf8JsonReader that contains additional state can shell out to a fully synchronous helper function that is able to create the needed types and perform the streaming read.

@mqudsi mqudsi closed this as completed Jun 16, 2019
@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@robertharvey416
Copy link

robertharvey416 commented Apr 29, 2020

@mqudsi: Can you help this fellow here? What might such an arrangement look like in code?
https://softwareengineering.stackexchange.com/questions/409479

@mqudsi
Copy link
Author

mqudsi commented Apr 29, 2020

@robertharvey416 replied with my (extremely dirty and not cleaned-up) code and an explanation. Thanks for the bat signal.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
area-System.Text.Json json-functionality-doc Missing JSON specific functionality that needs documenting
Projects
None yet
Development

No branches or pull requests

3 participants