11using System . Runtime . CompilerServices ;
22using System . Runtime . InteropServices ;
3+ using System . Threading . Tasks . Sources ;
34
45namespace DotNext . Runtime . CompilerServices ;
56
@@ -31,8 +32,9 @@ public struct SpawningAsyncTaskMethodBuilder<TResult>()
3132 public void Start < TStateMachine > ( ref TStateMachine stateMachine )
3233 where TStateMachine : IAsyncStateMachine
3334 {
34- var awaiter = System . Threading . Tasks . Task . Yield ( ) . GetAwaiter ( ) ;
35+ var awaiter = SpawningAsyncTaskMethodBuilder . Awaiter ;
3536 builder . AwaitUnsafeOnCompleted ( ref awaiter , ref stateMachine ) ;
37+ SpawningAsyncTaskMethodBuilder . Schedule ( ) ;
3638 }
3739
3840 /// <summary>
@@ -98,6 +100,11 @@ public void SetException(Exception e)
98100[ StructLayout ( LayoutKind . Auto ) ]
99101public struct SpawningAsyncTaskMethodBuilder ( )
100102{
103+ internal static readonly ConfiguredValueTaskAwaitable . ConfiguredValueTaskAwaiter Awaiter = new ValueTask ( new SpecialCallbackDetector ( ) , 0 ) . ConfigureAwait ( false ) . GetAwaiter ( ) ;
104+
105+ [ ThreadStatic ]
106+ private static ( Action < object ? > WorkItem , object ? State ) capturedArgs ;
107+
101108 private AsyncTaskMethodBuilder builder = AsyncTaskMethodBuilder . Create ( ) ;
102109
103110 /// <summary>
@@ -114,8 +121,9 @@ public struct SpawningAsyncTaskMethodBuilder()
114121 public void Start < TStateMachine > ( ref TStateMachine stateMachine )
115122 where TStateMachine : IAsyncStateMachine
116123 {
117- var awaiter = Task . Yield ( ) . GetAwaiter ( ) ;
124+ var awaiter = Awaiter ;
118125 builder . AwaitUnsafeOnCompleted ( ref awaiter , ref stateMachine ) ;
126+ Schedule ( ) ;
119127 }
120128
121129 /// <summary>
@@ -167,4 +175,23 @@ public void SetException(Exception e)
167175 /// Gets the task representing the builder's asynchronous operation.
168176 /// </summary>
169177 public Task Task => builder . Task ;
178+
179+ internal static void Schedule ( )
180+ {
181+ var ( continuation , state ) = capturedArgs ;
182+ capturedArgs = default ;
183+ ThreadPool . UnsafeQueueUserWorkItem ( continuation , state , preferLocal : false ) ;
184+ }
185+
186+ private sealed class SpecialCallbackDetector : IValueTaskSource
187+ {
188+ void IValueTaskSource . GetResult ( short token )
189+ {
190+ }
191+
192+ ValueTaskSourceStatus IValueTaskSource . GetStatus ( short token ) => ValueTaskSourceStatus . Pending ;
193+
194+ void IValueTaskSource . OnCompleted ( Action < object ? > continuation , object ? state , short token , ValueTaskSourceOnCompletedFlags flags )
195+ => capturedArgs = ( continuation , state ) ;
196+ }
170197}
0 commit comments