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

Improve ManualResetValueTaskSource prototype #29468

Merged
merged 1 commit into from
May 3, 2018

Conversation

stephentoub
Copy link
Member

In .NET Core 2.1 we added the public IValueTaskSource and IValueTaskSource<T> interfaces, with associated support in ValueTask and ValueTask<T>, and while we implemented the interfaces on several types internally, we didn't expose any public implementations.

We should consider exposing several in the future, including a manual-reset and an auto-reset IValueTaskSource implementation. We already have a ManualResetValueTaskSource implementation in our tests. This commit improves upon it in a few ways:

  • Separates out the logic into a separate public struct. The ManualResetValueTaskSource class wraps the struct, giving developers a choice to either use the class directly, or to embed the struct in their own implementation.
  • Fixes context capture to behave more similarly to Task, handling both SynchronizationContext and TaskSchedulers
  • Adds a prototype implementation of an IAsyncEnumerable, demonstrating how the compiler could utilize ManualResetValueTaskSourceLogic in its implementation.

This is all still prototype, used only in tests.

cc: @jcouv, @davidfowl, @kouvel, @tarekgh

In .NET Core 2.1 we added the public `IValueTaskSource` and `IValueTaskSource<T>` interfaces, with associated support in `ValueTask` and `ValueTask<T>`, and while we implemented the interfaces on several types internally, we didn't expose any public implementations.

We should consider exposing several in the future, including a manual-reset and an auto-reset IValueTaskSource implementation.  We already have a ManualResetValueTaskSource implementation in our tests.  This commit improves upon it in a few ways:
- Separates out the logic into a separate public struct.  The ManualResetValueTaskSource class wraps the struct, giving developers a choice to either use the class directly, or to embed the struct in their own implementation.
- Fixes context capture to behave more similarly to Task, handling both SynchronizationContext and TaskSchedulers
- Adds a prototype implementation of an IAsyncEnumerable, demonstrating how the compiler could utilize ManualResetValueTaskSourceLogic in its implementation.

This is all still prototype, used only in tests.
@stephentoub stephentoub merged commit df43abb into dotnet:master May 3, 2018
@stephentoub stephentoub deleted the mrvtschanges branch May 3, 2018 02:56
@davidfowl
Copy link
Member

So yield item in the async enumerable case will dispatch to the current scheduler.

@stephentoub
Copy link
Member Author

stephentoub commented May 3, 2018

So yield item in the async enumerable case will dispatch to the current scheduler.

With what I've prototyped out here:

  • Keep the ManualResetValueTaskSource{Logic} API separate in the discussion from IAsyncEnumerable: the former could have a configurable implementation based on properties exposed from it, e.g. a RunContinuationsAsynchronously property that it would respect, but the IAsyncEnumerable implementation generated by the compiler would need to make a policy decision about how to behave.
  • In what I have here, if MoveNextAsync completes synchronously, then nothing is dispatched: just as with async methods today, if the async method completes synchronously, the caller extracts the result synchronously, no callbacks.
  • If MoveNextAsync completes asynchronously, then if there was a non-default SynchronizationContext/TaskScheduler, as is the case with async methods today, yielding would result in queueing to that captured scheduler, as you suggest.
  • If MoveNextAsync completes asynchronously and either there wasn't a non-default SynchronizationContext/TaskScheduler, or if ConfigureAwait(false) was used on MoveNextAsync to avoid the context capture, then the yielding of the item would synchronously invoke the continuation.
  • As with await today, there is a race condition between the awaiter checking IsCompleted and then calling OnCompleted to hook up the callback, and the awaited operation completing. Task handles this as any good awaiter should, by saying that if the operation completes between the IsCompleted and the OnCompleted, then OnCompleted must queue the callback rather than invoking it synchronously, or else risk stack diving and stack overflows. I did the same thing here.

@karelz karelz added this to the 2.2.0 milestone May 5, 2018
baulig pushed a commit to mono/corefx that referenced this pull request Feb 4, 2019
In .NET Core 2.1 we added the public `IValueTaskSource` and `IValueTaskSource<T>` interfaces, with associated support in `ValueTask` and `ValueTask<T>`, and while we implemented the interfaces on several types internally, we didn't expose any public implementations.

We should consider exposing several in the future, including a manual-reset and an auto-reset IValueTaskSource implementation.  We already have a ManualResetValueTaskSource implementation in our tests.  This commit improves upon it in a few ways:
- Separates out the logic into a separate public struct.  The ManualResetValueTaskSource class wraps the struct, giving developers a choice to either use the class directly, or to embed the struct in their own implementation.
- Fixes context capture to behave more similarly to Task, handling both SynchronizationContext and TaskSchedulers
- Adds a prototype implementation of an IAsyncEnumerable, demonstrating how the compiler could utilize ManualResetValueTaskSourceLogic in its implementation.

This is all still prototype, used only in tests.

(cherry picked from commit df43abb)
baulig pushed a commit to mono/corefx that referenced this pull request Feb 4, 2019
In .NET Core 2.1 we added the public `IValueTaskSource` and `IValueTaskSource<T>` interfaces, with associated support in `ValueTask` and `ValueTask<T>`, and while we implemented the interfaces on several types internally, we didn't expose any public implementations.

We should consider exposing several in the future, including a manual-reset and an auto-reset IValueTaskSource implementation.  We already have a ManualResetValueTaskSource implementation in our tests.  This commit improves upon it in a few ways:
- Separates out the logic into a separate public struct.  The ManualResetValueTaskSource class wraps the struct, giving developers a choice to either use the class directly, or to embed the struct in their own implementation.
- Fixes context capture to behave more similarly to Task, handling both SynchronizationContext and TaskSchedulers
- Adds a prototype implementation of an IAsyncEnumerable, demonstrating how the compiler could utilize ManualResetValueTaskSourceLogic in its implementation.

This is all still prototype, used only in tests.

(cherry picked from commit df43abb)
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
In .NET Core 2.1 we added the public `IValueTaskSource` and `IValueTaskSource<T>` interfaces, with associated support in `ValueTask` and `ValueTask<T>`, and while we implemented the interfaces on several types internally, we didn't expose any public implementations.

We should consider exposing several in the future, including a manual-reset and an auto-reset IValueTaskSource implementation.  We already have a ManualResetValueTaskSource implementation in our tests.  This commit improves upon it in a few ways:
- Separates out the logic into a separate public struct.  The ManualResetValueTaskSource class wraps the struct, giving developers a choice to either use the class directly, or to embed the struct in their own implementation.
- Fixes context capture to behave more similarly to Task, handling both SynchronizationContext and TaskSchedulers
- Adds a prototype implementation of an IAsyncEnumerable, demonstrating how the compiler could utilize ManualResetValueTaskSourceLogic in its implementation.

This is all still prototype, used only in tests.

Commit migrated from dotnet/corefx@df43abb
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.

3 participants