@@ -558,54 +558,83 @@ private static bool QueueContinuationFollowUpActionIfNecessary<T, TOps>(T task,
558
558
#pragma warning disable CA1859
559
559
// When a Task-returning thunk gets a continuation result
560
560
// it calls here to make a Task that awaits on the current async state.
561
- private static Task < T ? > FinalizeTaskReturningThunk < T > ( Continuation continuation )
561
+ private static Task < T ? > FinalizeTaskReturningThunk < T > ( Continuation continuation , Exception ex )
562
562
{
563
- Continuation finalContinuation = new Continuation ( ) ;
564
-
565
- // Note that the exact location the return value is placed is tied
566
- // into getAsyncResumptionStub in the VM, so do not change this
567
- // without also changing that code (and the JIT).
568
- if ( RuntimeHelpers . IsReferenceOrContainsReferences < T > ( ) )
563
+ if ( continuation is not null )
569
564
{
570
- finalContinuation . Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ;
571
- finalContinuation . GCData = new object [ 1 ] ;
565
+ Continuation finalContinuation = new Continuation ( ) ;
566
+
567
+ // Note that the exact location the return value is placed is tied
568
+ // into getAsyncResumptionStub in the VM, so do not change this
569
+ // without also changing that code (and the JIT).
570
+ if ( RuntimeHelpers . IsReferenceOrContainsReferences < T > ( ) )
571
+ {
572
+ finalContinuation . Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ;
573
+ finalContinuation . GCData = new object [ 1 ] ;
574
+ }
575
+ else
576
+ {
577
+ finalContinuation . Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ;
578
+ finalContinuation . Data = new byte [ Unsafe . SizeOf < T > ( ) ] ;
579
+ }
580
+
581
+ continuation . Next = finalContinuation ;
582
+
583
+ ThunkTask < T ? > result = new ( ) ;
584
+ result . HandleSuspended ( continuation ) ;
585
+ return result ;
572
586
}
573
587
else
574
588
{
575
- finalContinuation . Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ;
576
- finalContinuation . Data = new byte [ Unsafe . SizeOf < T > ( ) ] ;
589
+ Task < T ? > task = new ( ) ;
590
+ // Tail of AsyncTaskMethodBuilderT.SetException
591
+ bool successfullySet = ex is OperationCanceledException oce ?
592
+ task . TrySetCanceled ( oce . CancellationToken , oce ) :
593
+ task . TrySetException ( ex ) ;
594
+
595
+ Debug . Assert ( successfullySet ) ;
596
+ return task ;
577
597
}
578
-
579
- continuation . Next = finalContinuation ;
580
-
581
- ThunkTask < T ? > result = new ( ) ;
582
- result . HandleSuspended ( continuation ) ;
583
- return result ;
584
598
}
585
599
586
- private static Task FinalizeTaskReturningThunk ( Continuation continuation )
600
+ private static Task FinalizeTaskReturningThunk ( Continuation continuation , Exception ex )
587
601
{
588
- Continuation finalContinuation = new Continuation
602
+ if ( continuation is not null )
589
603
{
590
- Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ,
591
- } ;
592
- continuation . Next = finalContinuation ;
604
+ Continuation finalContinuation = new Continuation
605
+ {
606
+ Flags = CorInfoContinuationFlags . CORINFO_CONTINUATION_NEEDS_EXCEPTION ,
607
+ } ;
608
+ continuation . Next = finalContinuation ;
593
609
594
- ThunkTask result = new ( ) ;
595
- result . HandleSuspended ( continuation ) ;
596
- return result ;
610
+ ThunkTask result = new ( ) ;
611
+ result . HandleSuspended ( continuation ) ;
612
+ return result ;
613
+ }
614
+ else
615
+ {
616
+ Debug . Assert ( ex is not null ) ;
617
+ Task task = new ( ) ;
618
+ // Tail of AsyncTaskMethodBuilderT.SetException
619
+ bool successfullySet = ex is OperationCanceledException oce ?
620
+ task . TrySetCanceled ( oce . CancellationToken , oce ) :
621
+ task . TrySetException ( ex ) ;
622
+
623
+ Debug . Assert ( successfullySet ) ;
624
+ return task ;
625
+ }
597
626
}
598
627
599
- private static ValueTask < T ? > FinalizeValueTaskReturningThunk < T > ( Continuation continuation )
628
+ private static ValueTask < T ? > FinalizeValueTaskReturningThunk < T > ( Continuation continuation , Exception ex )
600
629
{
601
630
// We only come to these methods in the expensive case (already
602
631
// suspended), so ValueTask optimization here is not relevant.
603
- return new ValueTask < T ? > ( FinalizeTaskReturningThunk < T > ( continuation ) ) ;
632
+ return new ValueTask < T ? > ( FinalizeTaskReturningThunk < T > ( continuation , ex ) ) ;
604
633
}
605
634
606
- private static ValueTask FinalizeValueTaskReturningThunk ( Continuation continuation )
635
+ private static ValueTask FinalizeValueTaskReturningThunk ( Continuation continuation , Exception ex )
607
636
{
608
- return new ValueTask ( FinalizeTaskReturningThunk ( continuation ) ) ;
637
+ return new ValueTask ( FinalizeTaskReturningThunk ( continuation , ex ) ) ;
609
638
}
610
639
611
640
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments