73 lines
2.0 KiB
C#
73 lines
2.0 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace ShrlAlgoToolkit.RevitCore.Base
|
|
{
|
|
public class ActionEventHandler : IExternalEventHandler
|
|
{
|
|
// 线程安全队列,用于存储需要传递给主线程执行的委托
|
|
private readonly ConcurrentQueue<Action<UIApplication>> _tasks = new ConcurrentQueue<Action<UIApplication>>();
|
|
private readonly ExternalEvent _externalEvent;
|
|
|
|
public ActionEventHandler()
|
|
{
|
|
_externalEvent = ExternalEvent.Create(this);
|
|
}
|
|
|
|
public void Execute(UIApplication app)
|
|
{
|
|
// 当主线程被 ExternalEvent 唤醒时,一次性执行队列中积累的所有任务
|
|
while (_tasks.TryDequeue(out var action))
|
|
{
|
|
action?.Invoke(app);
|
|
}
|
|
}
|
|
|
|
public string GetName() => "AsyncActionEventHandler";
|
|
|
|
// 无返回值的异步任务
|
|
public Task RaiseAsync(Action<UIApplication> action)
|
|
{
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
_tasks.Enqueue(app =>
|
|
{
|
|
try
|
|
{
|
|
action(app);
|
|
tcs.SetResult(true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
tcs.SetException(ex);
|
|
}
|
|
});
|
|
|
|
_externalEvent.Raise(); // 通知 Revit 唤醒事件
|
|
return tcs.Task;
|
|
}
|
|
|
|
// 有返回值的异步任务
|
|
public Task<T> RaiseAsync<T>(Func<UIApplication, T> func)
|
|
{
|
|
var tcs = new TaskCompletionSource<T>();
|
|
_tasks.Enqueue(app =>
|
|
{
|
|
try
|
|
{
|
|
var result = func(app);
|
|
tcs.SetResult(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
tcs.SetException(ex);
|
|
}
|
|
});
|
|
|
|
_externalEvent.Raise();
|
|
return tcs.Task;
|
|
}
|
|
}
|
|
}
|