using System.Threading.Tasks; using static System.Application.Services.IMainThreadPlatformService; namespace System.Application { /// /// 适用于桌面端的主线程帮助类,参考 Xamarin.Essentials.MainThread /// /// /// public static class MainThreadDesktop { public static bool IsMainThread => Instance.PlatformIsMainThread; public static void BeginInvokeOnMainThread(Action action, DispatcherPriority? priority = null) { if (IsMainThread) { action(); } else { Instance.PlatformBeginInvokeOnMainThread(action, priority); } } public static Task InvokeOnMainThreadAsync(Action action, DispatcherPriority? priority = null) { if (IsMainThread) { action(); #if NETSTANDARD1_0 return Task.FromResult(true); #else return Task.CompletedTask; #endif } var tcs = new TaskCompletionSource(); BeginInvokeOnMainThread(() => { try { action(); tcs.TrySetResult(true); } catch (Exception ex) { tcs.TrySetException(ex); } }, priority); return tcs.Task; } public static Task InvokeOnMainThreadAsync(Func func, DispatcherPriority? priority = null) { if (IsMainThread) { return Task.FromResult(func()); } var tcs = new TaskCompletionSource(); BeginInvokeOnMainThread(() => { try { var result = func(); tcs.TrySetResult(result); } catch (Exception ex) { tcs.TrySetException(ex); } }, priority); return tcs.Task; } public static Task InvokeOnMainThreadAsync(Func funcTask, DispatcherPriority? priority = null) { if (IsMainThread) { return funcTask(); } var tcs = new TaskCompletionSource(); BeginInvokeOnMainThread( async () => { try { await funcTask().ConfigureAwait(false); tcs.SetResult(null); } catch (Exception e) { tcs.SetException(e); } }, priority); return tcs.Task; } public static Task InvokeOnMainThreadAsync(Func> funcTask, DispatcherPriority? priority = null) { if (IsMainThread) { return funcTask(); } var tcs = new TaskCompletionSource(); BeginInvokeOnMainThread( async () => { try { var ret = await funcTask().ConfigureAwait(false); tcs.SetResult(ret); } catch (Exception e) { tcs.SetException(e); } }, priority); return tcs.Task; } /// /// An enunmeration describing the priorities at which /// operations can be invoked via the Dispatcher. /// /// /// public enum DispatcherPriority { /// /// Operations at this priority are processed when the system /// is idle. /// SystemIdle, /// /// Minimum possible priority /// MinValue = SystemIdle, /// /// Operations at this priority are processed when the application /// is idle. /// ApplicationIdle, /// /// Operations at this priority are processed when the context /// is idle. /// ContextIdle, /// /// Operations at this priority are processed after all other /// non-idle operations are done. /// Background, /// /// Operations at this priority are processed at the same /// priority as input. /// Input, /// /// Operations at this priority are processed when layout and render is /// done but just before items at input priority are serviced. Specifically /// this is used while firing the Loaded event /// Loaded, /// /// Operations at this priority are processed at the same /// priority as rendering. /// Render, /// /// Operations at this priority are processed at normal priority. /// Normal, /// /// Operations at this priority are processed before other /// asynchronous operations. /// Send, /// /// Maximum possible priority /// MaxValue = Send, } } }