| File: MainThread\MainThread.shared.cs | Web Access |
| Project: src\src\Essentials\src\Essentials.csproj (Microsoft.Maui.Essentials) |
using System; using System.Threading; using System.Threading.Tasks; namespace Microsoft.Maui.ApplicationModel { /// <summary> /// The MainThread class allows applications to run code on the main thread of execution, and to determine if a particular block of code is currently running on the main thread. /// </summary> public static partial class MainThread { /// <summary> /// True if the current thread is the UI thread. /// </summary> public static bool IsMainThread => PlatformIsMainThread; /// <summary> /// Invokes an action on the main thread of the application. /// </summary> /// <param name="action">The action to invoke on the main thread.</param> public static void BeginInvokeOnMainThread(Action action) { if (IsMainThread) { action(); } else { PlatformBeginInvokeOnMainThread(action); } } /// <summary> /// Invokes an action on the main thread of the application asynchronously. /// </summary> /// <param name="action">The action to invoke on the main thread.</param> /// <returns>A <see cref="Task"/> object with the current status of the asynchronous operation.</returns> public static Task InvokeOnMainThreadAsync(Action action) { if (IsMainThread) { action(); return Task.CompletedTask; } var tcs = new TaskCompletionSource<bool>(); BeginInvokeOnMainThread(() => { try { action(); tcs.TrySetResult(true); } catch (Exception ex) { tcs.TrySetException(ex); } }); return tcs.Task; } /// <summary> /// Invokes a function on the main thread of the application asynchronously. /// </summary> /// <typeparam name="T">Type of the object to be returned.</typeparam> /// <param name="func">The function task to execute on the main thread.</param> /// <returns>A <see cref="Task"/> object that can be awaited to capture the result object.</returns> public static Task<T> InvokeOnMainThreadAsync<T>(Func<T> func) { if (IsMainThread) { return Task.FromResult(func()); } var tcs = new TaskCompletionSource<T>(); BeginInvokeOnMainThread(() => { try { var result = func(); tcs.TrySetResult(result); } catch (Exception ex) { tcs.TrySetException(ex); } }); return tcs.Task; } /// <summary> /// Invokes a function on the main thread of the application asynchronously. /// </summary> /// <param name="funcTask">The function task to execute on the main thread.</param> /// <returns>A <see cref="Task"/> object that can be awaited.</returns> public static Task InvokeOnMainThreadAsync(Func<Task> funcTask) { if (IsMainThread) { return funcTask(); } var tcs = new TaskCompletionSource<object>(); BeginInvokeOnMainThread( async () => { try { await funcTask().ConfigureAwait(false); tcs.SetResult(null); } catch (Exception e) { tcs.SetException(e); } }); return tcs.Task; } /// <summary> /// Invokes a function on the main thread of the application asynchronously. /// </summary> /// <typeparam name="T">Type of the object to be returned.</typeparam> /// <param name="funcTask">The function task to execute on the main thread.</param> /// <returns>A <see cref="Task"/> object that can be awaited to capture the result object.</returns> public static Task<T> InvokeOnMainThreadAsync<T>(Func<Task<T>> funcTask) { if (IsMainThread) { return funcTask(); } var tcs = new TaskCompletionSource<T>(); BeginInvokeOnMainThread( async () => { try { var ret = await funcTask().ConfigureAwait(false); tcs.SetResult(ret); } catch (Exception e) { tcs.SetException(e); } }); return tcs.Task; } /// <summary> /// Gets the main thread synchonization context. /// </summary> /// <returns>The synchronization context for the main thread.</returns> public static async Task<SynchronizationContext> GetMainThreadSynchronizationContextAsync() { SynchronizationContext ret = null; await InvokeOnMainThreadAsync(() => ret = SynchronizationContext.Current).ConfigureAwait(false); return ret; } } }