mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-21 17:13:09 +08:00
207 lines
6.2 KiB
C#
207 lines
6.2 KiB
C#
using System.Threading.Tasks;
|
|
using static System.Application.Services.IMainThreadPlatformService;
|
|
|
|
namespace System.Application
|
|
{
|
|
/// <summary>
|
|
/// 适用于桌面端的主线程帮助类,参考 Xamarin.Essentials.MainThread
|
|
/// <para><see cref="https://docs.microsoft.com/zh-cn/xamarin/essentials/main-thread"/></para>
|
|
/// <para><see cref="https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/MainThread/MainThread.shared.cs"/></para>
|
|
/// </summary>
|
|
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<bool>();
|
|
|
|
BeginInvokeOnMainThread(() =>
|
|
{
|
|
try
|
|
{
|
|
action();
|
|
tcs.TrySetResult(true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
tcs.TrySetException(ex);
|
|
}
|
|
}, priority);
|
|
|
|
return tcs.Task;
|
|
}
|
|
|
|
public static Task<T> InvokeOnMainThreadAsync<T>(Func<T> func, DispatcherPriority? priority = null)
|
|
{
|
|
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);
|
|
}
|
|
}, priority);
|
|
|
|
return tcs.Task;
|
|
}
|
|
|
|
public static Task InvokeOnMainThreadAsync(Func<Task> funcTask, DispatcherPriority? priority = null)
|
|
{
|
|
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);
|
|
}
|
|
}, priority);
|
|
|
|
return tcs.Task;
|
|
}
|
|
|
|
public static Task<T> InvokeOnMainThreadAsync<T>(Func<Task<T>> funcTask, DispatcherPriority? priority = null)
|
|
{
|
|
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);
|
|
}
|
|
}, priority);
|
|
|
|
return tcs.Task;
|
|
}
|
|
|
|
/// <summary>
|
|
/// An enunmeration describing the priorities at which
|
|
/// operations can be invoked via the Dispatcher.
|
|
/// <see cref="https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherPriority.cs"/>
|
|
/// </summary>
|
|
///
|
|
public enum DispatcherPriority
|
|
{
|
|
/// <summary>
|
|
/// Operations at this priority are processed when the system
|
|
/// is idle.
|
|
/// </summary>
|
|
SystemIdle,
|
|
|
|
/// <summary>
|
|
/// Minimum possible priority
|
|
/// </summary>
|
|
MinValue = SystemIdle,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed when the application
|
|
/// is idle.
|
|
/// </summary>
|
|
ApplicationIdle,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed when the context
|
|
/// is idle.
|
|
/// </summary>
|
|
ContextIdle,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed after all other
|
|
/// non-idle operations are done.
|
|
/// </summary>
|
|
Background,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed at the same
|
|
/// priority as input.
|
|
/// </summary>
|
|
Input,
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
Loaded,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed at the same
|
|
/// priority as rendering.
|
|
/// </summary>
|
|
Render,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed at normal priority.
|
|
/// </summary>
|
|
Normal,
|
|
|
|
/// <summary>
|
|
/// Operations at this priority are processed before other
|
|
/// asynchronous operations.
|
|
/// </summary>
|
|
Send,
|
|
|
|
/// <summary>
|
|
/// Maximum possible priority
|
|
/// </summary>
|
|
MaxValue = Send,
|
|
}
|
|
}
|
|
} |