Skip to content

Commit f071d2b

Browse files
committed
Improved codegen, removed unnecessary allocations
The previous version caused the C# compiler to always instantiate a display class for the closure even if the execution had thread access
1 parent 899af46 commit f071d2b

File tree

2 files changed

+80
-59
lines changed

2 files changed

+80
-59
lines changed

Microsoft.Toolkit.Uwp/Helpers/DispatcherQueueHelper.cs

Lines changed: 79 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,28 @@ public static Task ExecuteOnUIThreadAsync(this DispatcherQueue dispatcher, Actio
4343
}
4444
}
4545

46-
var taskCompletionSource = new TaskCompletionSource<object>();
47-
48-
_ = dispatcher.TryEnqueue(priority, () =>
46+
static Task RunAsync(DispatcherQueue dispatcher, Action function, DispatcherQueuePriority priority)
4947
{
50-
try
51-
{
52-
function();
48+
var taskCompletionSource = new TaskCompletionSource<object>();
5349

54-
taskCompletionSource.SetResult(null);
55-
}
56-
catch (Exception e)
50+
_ = dispatcher.TryEnqueue(priority, () =>
5751
{
58-
taskCompletionSource.SetException(e);
59-
}
60-
});
52+
try
53+
{
54+
function();
55+
56+
taskCompletionSource.SetResult(null);
57+
}
58+
catch (Exception e)
59+
{
60+
taskCompletionSource.SetException(e);
61+
}
62+
});
6163

62-
return taskCompletionSource.Task;
64+
return taskCompletionSource.Task;
65+
}
66+
67+
return RunAsync(dispatcher, function, priority);
6368
}
6469

6570
/// <summary>
@@ -87,21 +92,26 @@ public static Task<T> ExecuteOnUIThreadAsync<T>(this DispatcherQueue dispatcher,
8792
}
8893
}
8994

90-
var taskCompletionSource = new TaskCompletionSource<T>();
91-
92-
_ = dispatcher.TryEnqueue(priority, () =>
95+
static Task<T> RunAsync(DispatcherQueue dispatcher, Func<T> function, DispatcherQueuePriority priority)
9396
{
94-
try
95-
{
96-
taskCompletionSource.SetResult(function());
97-
}
98-
catch (Exception e)
97+
var taskCompletionSource = new TaskCompletionSource<T>();
98+
99+
_ = dispatcher.TryEnqueue(priority, () =>
99100
{
100-
taskCompletionSource.SetException(e);
101-
}
102-
});
101+
try
102+
{
103+
taskCompletionSource.SetResult(function());
104+
}
105+
catch (Exception e)
106+
{
107+
taskCompletionSource.SetException(e);
108+
}
109+
});
103110

104-
return taskCompletionSource.Task;
111+
return taskCompletionSource.Task;
112+
}
113+
114+
return RunAsync(dispatcher, function, priority);
105115
}
106116

107117
/// <summary>
@@ -137,30 +147,35 @@ public static Task ExecuteOnUIThreadAsync(this DispatcherQueue dispatcher, Func<
137147
}
138148
}
139149

140-
var taskCompletionSource = new TaskCompletionSource<object>();
141-
142-
_ = dispatcher.TryEnqueue(priority, async () =>
150+
static Task RunAsync(DispatcherQueue dispatcher, Func<Task> function, DispatcherQueuePriority priority)
143151
{
144-
try
152+
var taskCompletionSource = new TaskCompletionSource<object>();
153+
154+
_ = dispatcher.TryEnqueue(priority, async () =>
145155
{
146-
if (function() is Task awaitableResult)
156+
try
147157
{
148-
await awaitableResult.ConfigureAwait(false);
149-
150-
taskCompletionSource.SetResult(null);
158+
if (function() is Task awaitableResult)
159+
{
160+
await awaitableResult.ConfigureAwait(false);
161+
162+
taskCompletionSource.SetResult(null);
163+
}
164+
else
165+
{
166+
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
167+
}
151168
}
152-
else
169+
catch (Exception e)
153170
{
154-
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
171+
taskCompletionSource.SetException(e);
155172
}
156-
}
157-
catch (Exception e)
158-
{
159-
taskCompletionSource.SetException(e);
160-
}
161-
});
173+
});
162174

163-
return taskCompletionSource.Task;
175+
return taskCompletionSource.Task;
176+
}
177+
178+
return RunAsync(dispatcher, function, priority);
164179
}
165180

166181
/// <summary>
@@ -193,30 +208,35 @@ public static Task<T> ExecuteOnUIThreadAsync<T>(this DispatcherQueue dispatcher,
193208
}
194209
}
195210

196-
var taskCompletionSource = new TaskCompletionSource<T>();
197-
198-
_ = dispatcher.TryEnqueue(priority, async () =>
211+
static Task<T> RunAsync(DispatcherQueue dispatcher, Func<Task<T>> function, DispatcherQueuePriority priority)
199212
{
200-
try
213+
var taskCompletionSource = new TaskCompletionSource<T>();
214+
215+
_ = dispatcher.TryEnqueue(priority, async () =>
201216
{
202-
if (function() is Task<T> awaitableResult)
217+
try
203218
{
204-
var result = await awaitableResult.ConfigureAwait(false);
205-
206-
taskCompletionSource.SetResult(result);
219+
if (function() is Task<T> awaitableResult)
220+
{
221+
var result = await awaitableResult.ConfigureAwait(false);
222+
223+
taskCompletionSource.SetResult(result);
224+
}
225+
else
226+
{
227+
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
228+
}
207229
}
208-
else
230+
catch (Exception e)
209231
{
210-
taskCompletionSource.SetException(new InvalidOperationException("The Task returned by function cannot be null."));
232+
taskCompletionSource.SetException(e);
211233
}
212-
}
213-
catch (Exception e)
214-
{
215-
taskCompletionSource.SetException(e);
216-
}
217-
});
234+
});
235+
236+
return taskCompletionSource.Task;
237+
}
218238

219-
return taskCompletionSource.Task;
239+
return RunAsync(dispatcher, function, priority);
220240
}
221241
}
222242
}

Microsoft.Toolkit.Uwp/Microsoft.Toolkit.Uwp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<Title>Windows Community Toolkit</Title>
66
<Description>This package includes code only helpers such as Colors conversion tool, Storage file handling, a Stream helper class, etc.</Description>
77
<PackageTags>UWP Toolkit Windows</PackageTags>
8+
<LangVersion>8.0</LangVersion>
89
</PropertyGroup>
910

1011
<ItemGroup>

0 commit comments

Comments
 (0)