using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Serein.Library.Utils { /// /// 为类库提供了在UI线程上下文操作的方法(使用Serein.Workbench时不用处理) /// 在WPF、Winform项目中,多线程中直接操作UI线程可能发生非预期的异常 /// 所以当你设置自己的平台时,需要手动实例化这个工具类 /// public class UIContextOperation { private SynchronizationContext context; private readonly Func getUiContext = null; static UIContextOperation() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { } } /// /// 传入UI线程上下文 /// /// 线程上下文 public UIContextOperation(SynchronizationContext synchronizationContext) { this.context = synchronizationContext; } /// /// 传入获取UI线程上下文的闭包创建 /// /// 获取线程上下文的闭包函数 public UIContextOperation(Func getUiContext) { this.getUiContext = getUiContext; } /// /// 同步方式在UI线程上进行调用方法 /// /// 要执行的UI操作 /// 异常发生时的回调 public void Invoke(Action uiAction, Action onException = null) { if(context is null && getUiContext != null) { context = getUiContext.Invoke(); } context?.Post(state => { try { uiAction?.Invoke(); } catch (Exception ex) { if(onException != null) onException(ex); Debug.WriteLine(ex); } }, null); } /// /// 异步方式进行调用 /// /// 要执行的UI操作 /// 异常发生时的回调 /// public Task InvokeAsync(Action uiAction, Action onException = null) { if (context is null && getUiContext != null) { context = getUiContext.Invoke(); } var tcs = new TaskCompletionSource(); context?.Post(state => { try { uiAction?.Invoke(); tcs.SetResult(true); } catch (Exception ex) { tcs.SetException(ex); if (onException != null) onException(ex); Debug.WriteLine(ex); } }, null); return tcs.Task; } } }