Exploring projecting WinRT async interfaces as custom Task
types
#114803
Replies: 2 comments
-
This is not exactly what you are asking for (defining a new type that extends https://github.com/dotnet/roslyn/blob/main/docs/features/task-types.md |
Beta Was this translation helpful? Give feedback.
-
It will be treated as a custom Task-like and will work, but will not be optimized in a way that an async2 function that awaits another async2 function. The whole point that you cannot use regular Task because your asynchronous API is sideeffecting in various ways, indicates that it cannot be optimized away. |
Beta Was this translation helpful? Give feedback.
-
As part of CsWinRT 3.0 (see .NET epic here), we're exploring possible improvements we could do on the projected API surface for .winmd-s, now that this breaking change (CsWinRT 3.0 itself) would give us a unique opportunity to do so. A common point of friction has always been the way WinRT async interfaces are projected to .NET, ie. the following types:
IAsyncAction
IAsyncActionWithProgress<TProgress>
IAsyncOperation<T>
IAsyncOperationWithProgress<T, TProgress>
Currently, these types are just projected as interfaces (matching the .winmd definition). This has always been a pain point:
AsTask
calls all over the place to actually get a normalTask
, whenever you need oneasync
method returning those typesNote
The main reason why we haven't just used
Task
andTask<T>
before is that doing so would lose a bunch of functionality exposed by those WinRT interfaces. Specifically, the fact you can attach some progress handler, and the other APIs defined on those types.We'd like to explore addressing at least the first two points. One idea that came up was to define custom types that extend
Task
andTask<T>
, so that we can have some projected types that areTask
types, but also expose the additional APIs. Something like:WindowsRuntimeTask
WindowsRuntimeTaskWithProgress<TProgress>
WindowsRuntimeTask<T>
WindowsRuntimeTaskWithProgress<T, TProgress>
Each of these would be a
Task
orTask
, and also wrap a reference to the native async object, so that it can implement the additional APIs for its underlying interface (eg.Completed
,Cancel()
, etc.). You'd also not need any conversion methods to/fromTask
-s anymore.The main problem with this is: we're not seeing any obvious way to actually define such a custom
Task
type. All the baseTask
constructors take someAction
orFunc<T>
, which we wouldn't actually have in this scenario (we are wrapping a native object).Task
types, would this also possibly be beneficial with respect to async2? (cc. @VSadov)Thank you! 🙂
cc. @stephentoub @jevansaks @manodasanW
Beta Was this translation helpful? Give feedback.
All reactions