Files

114 lines
4.3 KiB
C#
Raw Permalink Normal View History

2025-08-23 21:39:21 +08:00
using InkCanvasForClass.IccInkCanvas.Utils.Threading;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace InkCanvasForClass.IccInkCanvas {
/// <summary>
/// 基于 InkPresenter 优化和魔改的 InkBoard 控件
/// </summary>
public class InkBoard : FrameworkElement {
private readonly VisualCollection _children;
// Tuple 1为Dispatcher的Guid2为对应Dispatcher
private List<Tuple<Guid, Dispatcher>> _asyncDispatchers;
private const int HalfIntMax = 1073741823;
private const float HalfFloatMax = 1073741823f;
private const int QuarterSInt = 536756397;
private const float QuarterSFloat = 536756397f;
public InkBoard() {
VisualCacheMode = new BitmapCache(0);
ClipToBounds = true;
_children = new VisualCollection(this);
test();
}
#region Dispatchers
/// <summary>
/// 创建一个 Dispatcher
/// </summary>
/// <param name="customWorkerDispatcherName">如果可用,会使用这个名字创建Dispatcher(但是不会忽略GUID</param>
/// <returns>Tuple1为Guid2为Dispatcher</returns>
private async Task<Tuple<Guid, Dispatcher>> CreateDispathcer(string customWorkerDispatcherName = "IccInkCanvas") {
var guid = Guid.NewGuid();
var dispatcher = await UIDispatcher.RunNewAsync($"{customWorkerDispatcherName}_" + guid);
return new Tuple<Guid, Dispatcher>(guid, dispatcher);
}
/// <summary>
/// 注册一个新的 Dispatcher,这将会把 Dispatcher 给记录到 _asyncDispatchers 中
/// </summary>
/// <param name="customWorkerDispatcherName">如果可用,会使用这个名字创建Dispatcher(但是不会忽略GUID</param>
private async void RegisterNewDispatcher(string customWorkerDispatcherName = "IccInkCanvas") {
var dispatcher = await CreateDispathcer(customWorkerDispatcherName);
_asyncDispatchers.Add(dispatcher);
}
/// <summary>
/// 让一个 Dispatcher 停止工作并销毁
/// </summary>
/// <param name="dispatcher"></param>
private void DisposeDispatcher(Dispatcher dispatcher) {
dispatcher.BeginInvokeShutdown(DispatcherPriority.Send);
GC.Collect();
}
/// <summary>
/// 判断一个 Dispatcher 是否被挂起
/// </summary>
/// <param name="dispatcher"></param>
/// <returns></returns>
private static async Task<bool> CheckDispatcherHangAsync(Dispatcher dispatcher)
{
var taskCompletionSource = new TaskCompletionSource<bool>();
_ = dispatcher.InvokeAsync(() => taskCompletionSource.TrySetResult(true));
await Task.WhenAny(taskCompletionSource.Task, Task.Delay(TimeSpan.FromMilliseconds(1500)));
return taskCompletionSource.Task.IsCompleted is false;
}
#endregion
/// <summary>
/// 创建跨线程 InkPresenter,使用传入的 Dispatcher
/// </summary>
/// <returns></returns>
private async Task CreateInkPresenterWithDispatcher() {
await UIDispatcher.RunNewAsync("IccInkCanvas_" + Guid.NewGuid());
}
private async Task test() {
var di = new IccDispatcherInkCanvasInfo();
await di.InitDispatcher();
var control = await di.Dispatcher.InvokeAsync(() => new TextBlock() {
Text = "Helloworld!",
Foreground = new SolidColorBrush(Colors.Black),
FontSize = 24,
});
var dc = new DispatcherContainer();
await dc.SetChildAsync(control);
_children.Add(dc);
InvalidateVisual();
}
protected override int VisualChildrenCount {
get { return _children.Count; }
}
protected override Visual GetVisualChild(int index) {
if (index < 0 || index >= _children.Count) new ArgumentOutOfRangeException();
return _children[index];
}
}
}