@@ -37,21 +37,28 @@ public static class TaskExtensions
37
37
#endif
38
38
)
39
39
{
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 =
47
53
#if NETSTANDARD1_4
48
- task . GetType ( ) . GetRuntimeProperty ( nameof ( Task < object > . Result ) ) ;
54
+ task . GetType ( ) . GetRuntimeProperty ( nameof ( Task < object > . Result ) ) ;
49
55
#else
50
- task . GetType ( ) . GetProperty ( nameof ( Task < object > . Result ) ) ;
56
+ task . GetType ( ) . GetProperty ( nameof ( Task < object > . Result ) ) ;
51
57
#endif
52
58
53
- // Return the result, if possible
54
- return propertyInfo? . GetValue ( task ) ;
59
+ // Return the result, if possible
60
+ return propertyInfo? . GetValue ( task ) ;
61
+ }
55
62
}
56
63
57
64
return null ;
0 commit comments