Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Force secondary await continuations to run asynchronously #25280

Merged
merged 2 commits into from
Jun 24, 2019

Conversation

stephentoub
Copy link
Member

For performance reasons, await continuations have been invoked synchronously, meaning they're invoked as part of the antecedent task's completion (as long as that task allows it, as long as there's sufficient stack space, etc.) This generally works out well in the case where there's a single await continuation, which is far and away the common case. However, it can cause problems in situations where there are multiple await continuations, as those continuations will end up being serialized, which can lead to slowdowns and deadlocks in niche situations. To address that, this commit backs off a bit. The first await continuation is still invoked synchronously, but subsequent await continuations are invoked asynchronously, such that they are not blocked by a previously registered await continuation.

Fixes https://github.com/dotnet/corefx/issues/34781
cc: @tarekgh, @kouvel, @benaadams, @AArnott

For performance reasons, await continuations have been invoked synchronously, meaning they're invoked as part of the antecedent task's completion (as long as that task allows it, as long as there's sufficient stack space, etc.)  This generally works out well in the case where there's a single await continuation, which is far and away the common case.  However, it can cause problems in situations where there are multiple await continuations, as those continuations will end up being serialized, which can lead to slowdowns and deadlocks in niche situations.  To address that, this commit backs off a bit.  The first await continuation is still invoked synchronously, but subsequent await continuations are invoked asynchronously, such that they are not blocked by a previously registered await continuation.
@NinoFloris
Copy link

We have hit similar cases as described in dotnet/corefx#34781 so I'm super stoked to see this fixed!

Copy link

@AArnott AArnott left a comment

Choose a reason for hiding this comment

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

I can imagine an effective unit test to accompany this. Are you planning to add one?

@stephentoub
Copy link
Member Author

I can imagine an effective unit test to accompany this. Are you planning to add one?

Yes, in corefx.

@stephentoub stephentoub merged commit d58a283 into dotnet:master Jun 24, 2019
@stephentoub stephentoub deleted the taskcontinuations branch July 15, 2019 16:06
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…eclr#25280)

* Force secondary await continuations to run asynchronously

For performance reasons, await continuations have been invoked synchronously, meaning they're invoked as part of the antecedent task's completion (as long as that task allows it, as long as there's sufficient stack space, etc.)  This generally works out well in the case where there's a single await continuation, which is far and away the common case.  However, it can cause problems in situations where there are multiple await continuations, as those continuations will end up being serialized, which can lead to slowdowns and deadlocks in niche situations.  To address that, this commit backs off a bit.  The first await continuation is still invoked synchronously, but subsequent await continuations are invoked asynchronously, such that they are not blocked by a previously registered await continuation.

* Fix nits


Commit migrated from dotnet/coreclr@d58a283
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Execute only the first TPL Task continuation inline
5 participants