Skip to content

Replace Task.WaitAll with Task.WhenAll in async method. - #479

Merged
heejaechang merged 16 commits into
dotnet:masterfrom
AArnott:fix478
Feb 16, 2015
Merged

Replace Task.WaitAll with Task.WhenAll in async method.#479
heejaechang merged 16 commits into
dotnet:masterfrom
AArnott:fix478

Conversation

@AArnott

@AArnott AArnott commented Feb 13, 2015

Copy link
Copy Markdown
Contributor

Task.WaitAll has an overload that accepts a CancellationToken whereas the Task.WhenAll method does not. So I've added some useful extension methods that enable the same pattern you had before, but doing so in an async fashion rather than blocking a thread.

Fix #478

Task.WaitAll has an overload that accepts a CancellationToken whereas the Task.WhenAll method does not. So I've added some useful extension methods that enable the same pattern you had before, but doing so in an async fashion rather than blocking a thread.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is WithCancellation needed? simplifyTasks is already hot. if there is any cancellation, it will throw.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, Task.WhenAll already handles cancellation, doesn't it? I tried a quick and dirty experiment and i got a good OperationCanceledException out of it if any of the tasks were canceled. Not sure what if hte WithCancellation bit is needed.

This is what the docs say:

If any of the supplied tasks completes in a faulted state, the returned task will 
also complete in a Faulted state, where its exceptions will contain the aggregation 
of the set of unwrapped exceptions from each of the supplied tasks.

If none of the supplied tasks faulted but at least one of them was canceled, the
returned task will end in the Canceled state.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh.... i think i see. Task.WhenAll will only complete once all the inner tasks are done. You're trying to get it so that the task transitions immediately to cancelled if the cancellationToken triggers.

That's definitely interesting. Though is it necessary in practice? Are our inner reduction tasks not responding to cancellation quickly enough?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we change Task.WaitAll(...) to await Task.WhenAll(Tasks).ConfigureAwait(false)

don't we get most of benefit if not all? every tasks given to WhenAll in this particular case has cancellation token (in fact same cancellation token).

so, What WithCancellation trying to achieve here is not needed. also WithCancellation seems like kind of bandage solution where it tries to fix an issue where implementor of tasks didn't do proper cancellation management.

in Roslyn code base, if that is the case, I would say it is just a bug and fix the implementation of that task rather than use WithCancellation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole discussion seems to suggest I added the cancellationToken to the wait function. I did not. It was already there. I merely preserved prior behavior. The WaitAll method took a cancellationToken. This not only allowed the async method's Task to complete quickly upon cancellation regardless of the tasks it is waiting on, but it increased the odds that in that event an OperationCanceledException would be thrown instead of some other fault.
I'm happy to remove the WithCancellationToken extension method call if you would rather not have it though.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am on the side of just doing simple change for this case. I didn't mean to suggest that you added something that is not needed. sorry. :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. I just wanted to make sure we were on the same page about what would be a deviation in behavior. Is the simple change leaving the behavior as-is, or removing the cancellationToken from the WhenAll? I'll do either one.

@jasonmalinowski

Copy link
Copy Markdown
Member

Overall, now that I confirmed I can actually read code, 👍. My concern about the potential of abuse is still there, but I guess it's better we have the potential for abuse then the current actual abuse of the thread pool.

@AArnott

AArnott commented Feb 14, 2015

Copy link
Copy Markdown
Contributor Author

Well I'm still happy to remove WithCancellationToken and its use from the change if you feel it's unnecessary. The threadpool abuse will be resolved either way so long as we use WhenAll of course.

@CyrusNajmabadi

Copy link
Copy Markdown
Contributor

My personal preference would be to remove it. I think Roslyn's tasks are, in general, well behaved enough to not need this. And, if they aren't, they need to fixed. I think this method has the potential to mask bad behavior too much.

@CyrusNajmabadi

Copy link
Copy Markdown
Contributor

There are a bunch of commits added here that don't seem related to your change.

@AArnott

AArnott commented Feb 14, 2015

Copy link
Copy Markdown
Contributor Author

@CyrusNajmabadi The unrelated commits you see are an artifact from the fact that I merged master into my pull request branch to resolve merge conflicts. They aren't new to the target branch.

This in response to code review feedback with the expectation that the WhenAll's returned Task will complete quickly enough anyway upon cancellation because each task being awaited for cancels quickly upon request.
@jaredpar

Copy link
Copy Markdown
Member

A good chunk of these files are showing up as binary diffs now. Were they converted to UTF-16 on accident?

@AArnott

AArnott commented Feb 15, 2015

Copy link
Copy Markdown
Contributor Author

Git command line tools show that only the required files have any changes.
Github is just very confused.

On Sun, Feb 15, 2015, 10:58 AM Jared Parsons notifications@github.com
wrote:

A good chunk of these files are showing up as binary diffs now. Were they
converted to UTF-16 on accident?


Reply to this email directly or view it on GitHub
#479 (comment).

@jaredpar

Copy link
Copy Markdown
Member

@AArnott I've only seen GitHub classify a file as binary when Git does as well. We need to figure out what is going on here.

@jaredpar

Copy link
Copy Markdown
Member

@AArnott I just did a quick test where I merged your branch with dotnet/roslyn master and the diffs are coming out clean. It looks like you branched right around the last time we had to do some fix up from UTF-16 to UTF-8 and the diffs are just reflecting everything not being 100% up to date.

@AArnott

AArnott commented Feb 15, 2015

Copy link
Copy Markdown
Contributor Author

@jaredpar @CyrusNajmabadi Given the extra commits and files changed that GitHub reports that the git command line tools don't, I've submitted a support request to GitHub so at least they're aware of a potential bug in their online experience.

@jaredpar

Copy link
Copy Markdown
Member

Its strange. If u merge your branch with master and create a new PR it will show the true diff vs what it shows now. That's the behavior I saw.

JaredPar from a phone
http://blog.paranoidcoding.com/


From: Andrew Arnott notifications@github.com
Sent: Sunday, February 15, 2015 12:27:15 PM
To: dotnet/roslyn
Cc: Jared Parsons
Subject: Re: [roslyn] Replace Task.WaitAll with Task.WhenAll in async method. (#479)

@jaredparhttps://github.com/jaredpar @CyrusNajmabadihttps://github.com/CyrusNajmabadi Given the extra commits and files changed that GitHub reports that the git command line tools don't, I've submitted a support request to GitHub so at least they're aware of a potential bug in their online experience.

Reply to this email directly or view it on GitHubhttps://github.com//pull/479#issuecomment-74435106.

@heejaechang

Copy link
Copy Markdown
Contributor

@AArnott does this contain only WhenAll changes? if it is, then I can merge it to master. not sure why it shows all other changes.

@CyrusNajmabadi

Copy link
Copy Markdown
Contributor

It's not a terrible idea to just create a new branch at thsi point and just cherry-pick the ocmmits you care about into your new branch. You can then submit another review. I do this when something funky happens to a branch i'm working on.

@AArnott

AArnott commented Feb 16, 2015

Copy link
Copy Markdown
Contributor Author

@heejaechang Yes, this pull request contains just 5 lines or so changed in one file, per "git diff" between the two branches.
@CyrusNajmabadi It isn't a cherry-pick away, unfortunately. I tried that initially but because of the massive Src->src rename (and encoding changes perhaps) it wasn't trivial. So I'd rather leave it as it is.

@AArnott

AArnott commented Feb 16, 2015

Copy link
Copy Markdown
Contributor Author

I got a reply from github support on the extra commits and files changed that github claims are part of this pull request. In short, it's because the merge I made to resolve conflicts (due to the massive Src->src rename) had the parent branches of the merge commit in the reverse order from what their algorithm expected. There's more explanation, but that's the bottom line. It's a safe pull request to merge.

heejaechang pushed a commit that referenced this pull request Feb 16, 2015
Replace Task.WaitAll with Task.WhenAll in async method.
@heejaechang
heejaechang merged commit 0bf8a33 into dotnet:master Feb 16, 2015
@jaredpar

Copy link
Copy Markdown
Member

To close the loop the actual committed change was as simple as it should have been:

0bf8a33

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AbstractSimplificationService.ReduceAsync calls Task.WaitAll

8 participants