Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitCore/Base/ActionEventHandler.cs
2026-02-22 20:03:42 +08:00

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;
}
}
}