diff --git a/Microsoft.Toolkit.Uwp/Helpers/DispatcherHelper.cs b/Microsoft.Toolkit.Uwp/Helpers/DispatcherHelper.cs
index 1fb644509fa..e1389f5122e 100644
--- a/Microsoft.Toolkit.Uwp/Helpers/DispatcherHelper.cs
+++ b/Microsoft.Toolkit.Uwp/Helpers/DispatcherHelper.cs
@@ -15,73 +15,66 @@ namespace Microsoft.Toolkit.Uwp.Helpers
public static class DispatcherHelper
{
///
- /// Executes the given function asynchronously on UI thread of the main view.
+ /// Executes the given function on the main view's UI thread.
///
- /// Returned data type of the function
- /// Asynchronous function to be executed asynchronously on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task with type
- public static Task ExecuteOnUIThreadAsync(Func> function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Synchronous function to be executed on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task ExecuteOnUIThreadAsync(Action function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
+ return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given function on the main view's UI thread and returns its result.
///
- /// Returned data type of the function
- /// View for the to be executed on
- /// Asynchronous function to be executed asynchronously on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task with type
- public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func> function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Returned data type of the function.
+ /// Synchronous function to be executed on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task ExecuteOnUIThreadAsync(Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- if (viewToExecuteOn == null)
- {
- throw new ArgumentNullException(nameof(viewToExecuteOn));
- }
-
- return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
+ return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given -returning function on the main view's UI thread and returns either that
+ /// or a proxy that completes when the one produced by the given function completes.
///
- /// View for the to be executed on
- /// Asynchronous function to be executed asynchronously on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task
- public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Asynchronous function to be executed asynchronously on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ public static Task ExecuteOnUIThreadAsync(Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- if (viewToExecuteOn == null)
- {
- throw new ArgumentNullException(nameof(viewToExecuteOn));
- }
-
- return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
+ return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
}
///
- /// Executes the given function asynchronously on UI thread of the main view.
+ /// Executes the given -returning function on the main view's UI thread and returns either that
+ /// or a proxy that completes when the one produced by the given function completes.
///
- /// Asynchronous function to be executed asynchronously on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task
- public static Task ExecuteOnUIThreadAsync(Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Returned data type of the function.
+ /// Asynchronous function to be executed asynchronously on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ public static Task ExecuteOnUIThreadAsync(Func> function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given function on a given view's UI thread.
///
- /// View for the to be executed on
- /// Asynchronous function to be executed asynchronously on UI thread
+ /// View for the to be executed on.
+ /// Synchronous function to be executed on UI thread.
/// Dispatcher execution priority, default is normal
- /// Awaitable Task/>
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Action function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- if (viewToExecuteOn == null)
+ if (viewToExecuteOn is null)
{
throw new ArgumentNullException(nameof(viewToExecuteOn));
}
@@ -90,77 +83,148 @@ public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecute
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given function on a given view's UI thread.
///
- /// Asynchronous function to be executed asynchronously on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task/>
- public static Task ExecuteOnUIThreadAsync(Action function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Returned data type of the function.
+ /// View for the to be executed on.
+ /// Synchronous function with return type to be executed on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
+ if (viewToExecuteOn is null)
+ {
+ throw new ArgumentNullException(nameof(viewToExecuteOn));
+ }
+
+ return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given function on a given view's UI thread.
///
- /// Returned data type of the function
- /// View for the to be executed on
- /// Synchronous function with return type to be executed on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task with type
- public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// View for the to be executed on.
+ /// Asynchronous function to be executed asynchronously on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- if (viewToExecuteOn == null)
+ if (viewToExecuteOn is null)
{
throw new ArgumentNullException(nameof(viewToExecuteOn));
}
- return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
+ return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
}
///
- /// Executes the given function asynchronously on given view's UI thread. Default view is the main view.
+ /// Executes the given function on a given view's UI thread.
///
- /// Returned data type of the function
- /// Synchronous function to be executed on UI thread
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task
- public static Task ExecuteOnUIThreadAsync(Func function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Returned data type of the function.
+ /// View for the to be executed on.
+ /// Asynchronous function to be executed asynchronously on UI thread.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task ExecuteOnUIThreadAsync(this CoreApplicationView viewToExecuteOn, Func> function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- return ExecuteOnUIThreadAsync(CoreApplication.MainView, function, priority);
+ if (viewToExecuteOn is null)
+ {
+ throw new ArgumentNullException(nameof(viewToExecuteOn));
+ }
+
+ return viewToExecuteOn.Dispatcher.AwaitableRunAsync(function, priority);
}
///
- /// Extension method for CoreDispatcher. Offering an actual awaitable Task with optional result that will be executed on the given dispatcher
+ /// Extension method for . Offering an actual awaitable with optional result that will be executed on the given dispatcher.
///
- /// Returned data type of the function
- /// Dispatcher of a thread to run
- /// Asynchrounous function to be executed asynchrounously on the given dispatcher
- /// Dispatcher execution priority, default is normal
- /// Awaitable Task with type
- public static Task AwaitableRunAsync(this CoreDispatcher dispatcher, Func> function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
+ /// Dispatcher of a thread to run .
+ /// Function to be executed on the given dispatcher.
+ /// Dispatcher execution priority, default is normal.
+ /// An awaitable for the operation.
+ /// If the current thread has UI access, will be invoked directly.
+ public static Task AwaitableRunAsync(this CoreDispatcher dispatcher, Action function, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
{
- if (function == null)
+ if (function is null)
{
throw new ArgumentNullException(nameof(function));
}
+ /* Run the function directly when we have thread access.
+ * Also reuse Task.CompletedTask in case of success,
+ * to skip an unnecessary heap allocation for every invocation. */
+ if (dispatcher.HasThreadAccess)
+ {
+ try
+ {
+ function();
+
+ return Task.CompletedTask;
+ }
+ catch (Exception e)
+ {
+ return Task.FromException(e);
+ }
+ }
+
+ var taskCompletionSource = new TaskCompletionSource