@@ -37,21 +37,28 @@ public static class TaskExtensions
3737#endif
3838 )
3939 {
40- // Try to get the Task<T>.Result property. This method would've
41- // been called anyway after the type checks, but using that to
42- // validate the input type saves some additional reflection calls.
43- // Furthermore, doing this also makes the method flexible enough to
44- // cases whether the input Task<T> is actually an instance of some
45- // runtime-specific type that inherits from Task<T>.
46- PropertyInfo ? propertyInfo =
40+ // We need an explicit check to ensure the input task is not the cached
41+ // Task.CompletedTask instance, because that can internally be stored as
42+ // a Task<T> for some given T (eg. on .NET 5 it's VoidTaskResult), which
43+ // would cause the following code to return that result instead of null.
44+ if ( task != Task . CompletedTask )
45+ {
46+ // Try to get the Task<T>.Result property. This method would've
47+ // been called anyway after the type checks, but using that to
48+ // validate the input type saves some additional reflection calls.
49+ // Furthermore, doing this also makes the method flexible enough to
50+ // cases whether the input Task<T> is actually an instance of some
51+ // runtime-specific type that inherits from Task<T>.
52+ PropertyInfo ? propertyInfo =
4753#if NETSTANDARD1_4
48- task . GetType ( ) . GetRuntimeProperty ( nameof ( Task < object > . Result ) ) ;
54+ task . GetType ( ) . GetRuntimeProperty ( nameof ( Task < object > . Result ) ) ;
4955#else
50- task . GetType ( ) . GetProperty ( nameof ( Task < object > . Result ) ) ;
56+ task . GetType ( ) . GetProperty ( nameof ( Task < object > . Result ) ) ;
5157#endif
5258
53- // Return the result, if possible
54- return propertyInfo? . GetValue ( task ) ;
59+ // Return the result, if possible
60+ return propertyInfo? . GetValue ( task ) ;
61+ }
5562 }
5663
5764 return null ;
0 commit comments