Add async document/element loading for XLinq. #110
Conversation
Love it |
First of all, I want to say thank-you for your contribution. This looks like a lot of great work and is the first contribution that we've had with API additions! At the moment, we're right in the middle of bringing our API review process out in the open - and we're not immediately ready to take on this change. Over the next couple of weeks we'll work with you and use this PR as the guinea pig of the process. In the meantime, we'll provide some feedback on the pull request itself. |
Sounds great, lets figure out this process. I'll do my best to address feedback. |
I really like the idea of these new async APIs. I'll do my best to push it :) Good job! |
…ith sync methods. This is needed due to them creating XmlReaderSettings using undocumented functionality based on the given LoadOptions.
Verification is admittedly difficult without a test harness for the project. I (minimally) checked myself by using the monster JMDict file, loading/saving both in 4.5.2 and with the new sync/async variants to verify the output was identical. |
Has anyone had a chance to look at this yet? |
Apologies, we haven't forgotten about this. There's two things that we're working on that are preventing us from taking this right at this moment:
|
Thanks for your continued patience, @terrajobst has just posted our API Review process proposal, feel free to comment over here: https://github.com/dotnet/corefx/issues/294. |
/// significant whitespace will be preserved. | ||
/// </returns> | ||
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", Justification = "Back-compat with System.Xml.")] | ||
public static async Task<XElement> Load(string uri, LoadOptions options, CancellationToken token) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this named LoadAsync
?
The proposed For example: public static Task<XDocument> LoadAsync(string uri, LoadOptions options)
{
return LoadAsync(uri, options, CancellationToken.None);
}
public static async Task<XDocument> LoadAsync(string uri, LoadOptions options, CancellationToken token)
{
...
} |
Also, most existing methods in the Framework that take a |
re: "token" vs "cancellationToken", you're right, and I'd rather maintain consistency with existing conventions. I'll change that. re: overloads that don't support cancellation, I didn't include them simply because I never use them (why implement an async API if you won't support cancellation?) and didn't think about it. I can add if wanted. |
I'll let the official API reviewers weigh in, but this is mentioned in the Task-based Asynchronous Pattern (TAP) design guidelines:
|
ContentReader cr = new ContentReader(this); | ||
while (!token.IsCancellationRequested && cr.ReadContentFrom(this, r, o) && await r.ReadAsync().ConfigureAwait(false)) ; | ||
|
||
token.ThrowIfCancellationRequested(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, cancellation should not be checked for / cause an exception after the relevant work has already completed. This loop should be restructured such that ThrowIfCancellationRequested occurs where you currently poll IsCancellationRequested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, will change.
We've reviewed these APIs. We're OK with adding these APIs but in order to be complete, |
Can one of the admins approve this PR test or whitelist this user? ('@dotnet-bot add to whitelist' to whitelist, '@dotnet-bot okay to test' to accept for PR, '@dotnet-bot test this please' to retest. Case sensitive). |
1 similar comment
Can one of the admins approve this PR test or whitelist this user? ('@dotnet-bot add to whitelist' to whitelist, '@dotnet-bot okay to test' to accept for PR, '@dotnet-bot test this please' to retest. Case sensitive). |
Thank you @terrajobst. In addition to Save(), there is also XNode.ReadFrom() and XNode.WriteTo() which should get an async implementation. I will add these to the PR. I excluded Save() initially due to there not really being a clean way to implement... will involve essentially duplicating all relevant implementation. |
@scalablecory, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR. |
public static async Task<XNode> ReadFromAsync(XmlReader reader, CancellationToken cancellationToken) | ||
{ | ||
if (reader == null) throw new ArgumentNullException("reader"); | ||
if (reader.ReadState != ReadState.Interactive) throw new InvalidOperationException(SR.InvalidOperation_ExpectedInteractive); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about separating out usage errors into non-async methods.
Maybe I just missed them or discussion of them, but are there tests to accompany the new APIs? |
@scalablecory We've changed our branching strategy in a way that impacts this PR. When you're ready to continue work on this, you'll need to either recreate the PR against the 'future' branch or wait until after we have snapped the first release branch before we can merge it in to master. |
Hrm, I wonder if I could rebase it to keep the same PR. |
Unfortunately you can't change the target branch of an existing PR. You have to close this and open a new one targeted at the new branch. 😭 Add your 👍 here: isaacs/github#18 😉 |
@scalablecory , it is so simple! :just-kidding: :) cd \my\projects\path\corefx
git remote add corefx https://github.com/dotnet/corefx
git fetch corefx
git checkout future
git merge --no-ff master
# resolve conflicts
# add more commits, for example, addressing review comments here
git push Then future...scalablecory:future and open a new PR, where you reference the link to this PR in description to retain the comment history / all this interesting conversation. :) |
@scalablecory, just checking in on this. Do you need any assistance in order to move forward? |
@stephentoub Someone reorganized the master repo without using "git mv" and it wrecked my merge. I'm finding some time to redo the changes against future. |
JFYI, Git doesn't store move/rename information. |
@stephentoub, since OP is having trouble with rebasing; would it make sense if this gets superseded by a separate PR, for instance, with an additional commit of yours fixing the merge conflicts? |
It's up to Cory whether he'd like that or not. |
@scalablecory, are you still pursuing this? Otherwise someone else can rebase these commits on your behalf and send a new PR. |
@stephentoub If you've got the time to fix this patch, please do! I'm unfortunately too busy to follow through. |
Ok, I'll see what I can do. Thanks. |
Replaced by #2436. |
Adds XElement.LoadAsync and XDocument.LoadAsync. Code from the sync versions has been largely lifted out so they can share an implementation as much as possible.