Skip to content

Commit b22c115

Browse files
Merge pull request #4790 from michael-hawker/llama/fix4505
TaskResultConverter returns default value when task not set
2 parents aa39ee5 + e3fe539 commit b22c115

File tree

2 files changed

+59
-33
lines changed

2 files changed

+59
-33
lines changed

Microsoft.Toolkit.Uwp.UI/Converters/TaskResultConverter.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
1414
/// This is needed because accessing <see cref="Task{TResult}.Result"/> when the task has not
1515
/// completed yet will block the current thread and might cause a deadlock (eg. if the task was
1616
/// scheduled on the same synchronization context where the result is being retrieved from).
17-
/// The methods in this converter will safely return <see langword="default"/> if the input
18-
/// task is still running, or if it has faulted or has been canceled.
17+
/// The methods in this converter will safely return <see langword="null"/> if the input
18+
/// task is not set yet, still running, has faulted, or has been canceled.
1919
/// </summary>
2020
public sealed class TaskResultConverter : IValueConverter
2121
{
@@ -26,8 +26,13 @@ public object Convert(object value, Type targetType, object parameter, string la
2626
{
2727
return task.GetResultOrDefault();
2828
}
29+
else if (value is null)
30+
{
31+
return null;
32+
}
2933

30-
return DependencyProperty.UnsetValue;
34+
// Otherwise, we'll just pass through whatever value/result was given to us.
35+
return value;
3136
}
3237

3338
/// <inheritdoc/>

UnitTests/UnitTests.UWP/Converters/Test_TaskResultConverter.cs

+51-30
Original file line numberDiff line numberDiff line change
@@ -17,97 +17,118 @@ public class Test_TaskResultConverter
1717
{
1818
[TestCategory("Converters")]
1919
[UITestMethod]
20+
[Ignore] // Ignore this value type test. Behavior will return null currently and not default.
2021
public void Test_TaskResultConverter_Instance_Int32()
2122
{
22-
var converter = new TaskResultConverter();
23+
TaskResultConverter converter = new();
2324

24-
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
25+
TaskCompletionSource<int> tcs = new();
2526

26-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
27+
Assert.AreEqual(0, (int)converter.Convert(tcs.Task, typeof(int), null, null));
2728

2829
tcs.SetCanceled();
2930

30-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
31+
Assert.AreEqual(0, (int)converter.Convert(tcs.Task, typeof(int), null, null));
3132

3233
tcs = new TaskCompletionSource<int>();
3334

3435
tcs.SetException(new InvalidOperationException("Test"));
3536

36-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
37+
Assert.AreEqual(0, (int)converter.Convert(tcs.Task, typeof(int), null, null));
3738

3839
tcs = new TaskCompletionSource<int>();
3940

4041
tcs.SetResult(42);
4142

42-
Assert.AreEqual(42, converter.Convert(tcs.Task, null, null, null));
43+
Assert.AreEqual(42, (int)converter.Convert(tcs.Task, typeof(int), null, null));
4344
}
4445

4546
[TestCategory("Converters")]
4647
[UITestMethod]
4748
public void Test_TaskResultConverter_Instance_String()
4849
{
49-
var converter = new TaskResultConverter();
50+
TaskResultConverter converter = new();
5051

51-
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
52+
TaskCompletionSource<string> tcs = new();
5253

53-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
54+
Assert.AreEqual(null, (string)converter.Convert(tcs.Task, typeof(string), null, null));
5455

5556
tcs.SetCanceled();
5657

57-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
58+
Assert.AreEqual(null, (string)converter.Convert(tcs.Task, typeof(string), null, null));
5859

59-
tcs = new TaskCompletionSource<string>();
60+
tcs = new();
6061

6162
tcs.SetException(new InvalidOperationException("Test"));
6263

63-
Assert.AreEqual(null, converter.Convert(tcs.Task, null, null, null));
64+
Assert.AreEqual(null, (string)converter.Convert(tcs.Task, typeof(string), null, null));
6465

65-
tcs = new TaskCompletionSource<string>();
66+
tcs = new();
6667

6768
tcs.SetResult("Hello world");
6869

69-
Assert.AreEqual("Hello world", converter.Convert(tcs.Task, null, null, null));
70+
Assert.AreEqual("Hello world", (string)converter.Convert(tcs.Task, typeof(string), null, null));
7071
}
7172

7273
[TestCategory("Converters")]
7374
[UITestMethod]
74-
public void Test_TaskResultConverter_Instance_UnsetValue()
75+
public void Test_TaskResultConverter_Instance_RawValue()
7576
{
76-
var converter = new TaskResultConverter();
77+
TaskResultConverter converter = new();
7778

78-
Assert.AreEqual(DependencyProperty.UnsetValue, converter.Convert(null, null, null, null));
79-
Assert.AreEqual(DependencyProperty.UnsetValue, converter.Convert("Hello world", null, null, null));
79+
Assert.AreEqual(42, converter.Convert(42, null, null, null));
80+
81+
Assert.AreEqual(42, converter.Convert(42, typeof(int), null, null));
82+
83+
Assert.AreEqual("Hello world", converter.Convert("Hello world", null, null, null));
84+
85+
Assert.AreEqual("Hello world", converter.Convert("Hello world", typeof(string), null, null));
8086
}
8187

8288
[TestCategory("Converters")]
8389
[UITestMethod]
84-
public void Test_TaskResultConverter_Instance_Null()
90+
public void Test_TaskResultConverter_Instance_NullObject()
8591
{
86-
var converter = new TaskResultConverter();
92+
TaskResultConverter converter = new();
8793

88-
var cts = new CancellationTokenSource();
94+
Assert.AreEqual(null, converter.Convert(null, null, null, null));
8995

90-
cts.Cancel();
96+
// TODO: Think there may still be a problem for value types in x:Bind expressions, represented by these tests here,
97+
// but was going to be too big a change for 7.1.3, will have to get more feedback and evaluate later.
98+
/*Assert.AreEqual(0, (int)converter.Convert(null, typeof(int), null, null));
9199
92-
Assert.AreEqual(null, converter.Convert(Task.FromCanceled(cts.Token), null, null, null));
93-
Assert.AreEqual(null, converter.Convert(Task.FromException(new Exception()), null, null, null));
94-
Assert.AreEqual(null, converter.Convert(Task.CompletedTask, null, null, null));
100+
Assert.AreEqual(false, (bool)converter.Convert(null, typeof(bool), null, null));*/
95101

96-
TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>();
102+
Assert.AreEqual(null, converter.Convert(null, typeof(int), null, null));
97103

98-
Assert.AreEqual(null, converter.Convert(tcs1.Task, null, null, null));
104+
Assert.AreEqual(null, converter.Convert(null, typeof(bool), null, null));
99105

100-
TaskCompletionSource<string> tcs2 = new TaskCompletionSource<string>();
106+
Assert.AreEqual(null, (int?)converter.Convert(null, typeof(int?), null, null));
101107

102-
Assert.AreEqual(null, converter.Convert(tcs2.Task, null, null, null));
108+
Assert.AreEqual(null, (string)converter.Convert(null, typeof(string), null, null));
109+
}
110+
111+
[TestCategory("Converters")]
112+
[UITestMethod]
113+
public void Test_TaskResultConverter_Instance_TaskNull()
114+
{
115+
TaskResultConverter converter = new();
116+
117+
CancellationTokenSource cts = new();
118+
119+
cts.Cancel();
120+
121+
Assert.AreEqual(null, converter.Convert(Task.FromCanceled(cts.Token), null, null, null));
122+
Assert.AreEqual(null, converter.Convert(Task.FromException(new Exception()), null, null, null));
123+
Assert.AreEqual(null, converter.Convert(Task.CompletedTask, null, null, null));
103124
}
104125

105126
[TestCategory("Converters")]
106127
[UITestMethod]
107128
[ExpectedException(typeof(NotImplementedException))]
108129
public void Test_TaskResultConverter_Instance_ConvertBack()
109130
{
110-
var converter = new TaskResultConverter();
131+
TaskResultConverter converter = new();
111132

112133
Assert.AreEqual(null, converter.ConvertBack(null, null, null, null));
113134
}

0 commit comments

Comments
 (0)