using System;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Windows.Threading;
using JetBrains.Annotations;
namespace InkCanvasForClass.IccInkCanvas.Utils.Threading
{
///
/// 包含扩展 的一些方法。
///
public static class UIDispatcher
{
///
/// 创建一个可以运行 的后台 UI 线程,并返回这个线程的调度器 。
///
/// 线程的名称,如果不指定,将使用 “BackgroundUI”。
/// 一个可以异步等待的 。
public static DispatcherAsyncOperation RunNewAsync([CanBeNull] string name = null)
{
// 创建一个可等待的异步操作。
var awaiter = DispatcherAsyncOperation.Create(out var reportResult);
// 记录原线程关联的 Dispatcher,以便在意外时报告异常。
var originDispatcher = Dispatcher.CurrentDispatcher;
// 创建后台线程。
var thread = new Thread(() =>
{
try
{
// 获取关联此后台线程的 Dispatcher。
var dispatcher = Dispatcher.CurrentDispatcher;
// 设置此线程的 SynchronizationContext,以便此线程上 await 之后能够返回此线程。
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(dispatcher));
// 报告 Dispatcher 已创建完毕,使用 await 异步等待 Dispatcher 创建的地方可以继续执行了。
reportResult(dispatcher, null);
}
catch (Exception ex)
{
// 报告创建过程中发生的异常。
// 不需要担心其内部发生的异常,因为会被异步状态机捕获后重新在原线程上抛出。
reportResult(null, ex);
}
// 此线程的以下代码将脱离异步状态机的控制,需要自己处理异常。
try
{
// 启动 Dispatcher,开始此线程上消息的调度。
Dispatcher.Run();
}
catch (Exception ex)
{
// 如果新的 Dispatcher 线程上出现了未处理的异常,则将其抛到原调用线程上。
originDispatcher.InvokeAsync(() => ExceptionDispatchInfo.Capture(ex).Throw());
}
})
{
Name = name ?? "BackgroundUI",
IsBackground = true,
};
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return awaiter;
}
///
/// 创建一个可以运行 的后台 UI 线程,并返回这个线程的调度器 。
///
/// 线程的名称,如果不指定,将使用 “BackgroundUI”。
/// 后台线程创建并启动的 。
public static Dispatcher RunNew([CanBeNull] string name = null)
{
var resetEvent = new AutoResetEvent(false);
// 记录原线程关联的 Dispatcher,以便在意外时报告异常。
var originDispatcher = Dispatcher.CurrentDispatcher;
Exception innerException = null;
Dispatcher dispatcher = null;
// 创建后台线程。
var thread = new Thread(() =>
{
try
{
// 获取关联此后台线程的 Dispatcher。
dispatcher = Dispatcher.CurrentDispatcher;
// 设置此线程的 SynchronizationContext,以便此线程上 await 之后能够返回此线程。
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(dispatcher));
// 报告 Dispatcher 已创建完毕,使用 ResetEvent 同步等待 Dispatcher 创建的地方可以继续执行了。
resetEvent.Set();
}
catch (Exception ex)
{
// 报告创建过程中发生的异常。
innerException = ex;
resetEvent.Set();
}
// 此线程的以下代码将脱离异步状态机的控制,需要自己处理异常。
try
{
// 启动 Dispatcher,开始此线程上消息的调度。
Dispatcher.Run();
}
catch (Exception ex)
{
// 如果新的 Dispatcher 线程上出现了未处理的异常,则将其抛到原调用线程上。
originDispatcher.InvokeAsync(() => ExceptionDispatchInfo.Capture(ex).Throw());
}
})
{
Name = name ?? "BackgroundUI",
IsBackground = true,
};
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
resetEvent.WaitOne();
resetEvent.Dispose();
resetEvent = null;
if (innerException != null)
{
ExceptionDispatchInfo.Capture(innerException).Throw();
}
return dispatcher;
}
}
}