Skip to content

Commit 63bfd70

Browse files
authored
Merge branch 'master' into patch-1
2 parents d4d69d7 + 949bab9 commit 63bfd70

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

Microsoft.Toolkit/Extensions/TaskExtensions.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

UnitTests/UnitTests.Shared/Extensions/Test_TaskExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ public void Test_TaskExtensions_ResultOrDefault()
3737
Assert.AreEqual(42, ((Task)tcs.Task).GetResultOrDefault());
3838
}
3939

40+
[TestCategory("TaskExtensions")]
41+
[TestMethod]
42+
public void Test_TaskExtensions_ResultOrDefault_FromTaskCompleted()
43+
{
44+
Assert.AreEqual(null, Task.CompletedTask.GetResultOrDefault());
45+
}
46+
4047
[TestCategory("TaskExtensions")]
4148
[TestMethod]
4249
public async Task Test_TaskExtensions_ResultOrDefault_FromAsyncTaskMethodBuilder()

0 commit comments

Comments
 (0)