调整代码
This commit is contained in:
72
ShrlAlgoToolkit.RevitCore/Base/ActionEventHandler.cs
Normal file
72
ShrlAlgoToolkit.RevitCore/Base/ActionEventHandler.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
64
ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs
Normal file
64
ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using ShrlAlgoToolkit.RevitCore.Base;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitCore.Assists
|
||||
{
|
||||
public abstract class BaseApplication : IExternalApplication
|
||||
{
|
||||
public UIControlledApplication UiApplication { get; private set; }
|
||||
|
||||
public Result OnStartup(UIControlledApplication application)
|
||||
{
|
||||
UiApplication = application;
|
||||
|
||||
// 1. 注册程序集依赖解析事件 (解决第三方库找不到的问题)
|
||||
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
|
||||
|
||||
// 2. 初始化全局异步外部事件处理器 (必须在主线程创建)
|
||||
ExternalEventHelper.Initialize();
|
||||
|
||||
try
|
||||
{
|
||||
OnApplicationStartup();
|
||||
return Result.Succeeded;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
TaskDialog.Show("Startup Error", ex.ToString());
|
||||
return Result.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
public Result OnShutdown(UIControlledApplication application)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnApplicationShutdown();
|
||||
return Result.Succeeded;
|
||||
}
|
||||
finally
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve;
|
||||
}
|
||||
}
|
||||
|
||||
// 供子类重写的方法
|
||||
public abstract void OnApplicationStartup();
|
||||
public virtual void OnApplicationShutdown() { }
|
||||
|
||||
// 依赖自动解析逻辑
|
||||
private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name).Name;
|
||||
var pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
var assemblyPath = Path.Combine(pluginDirectory, $"{assemblyName}.dll");
|
||||
|
||||
return File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
ShrlAlgoToolkit.RevitCore/Base/BaseCommand.cs
Normal file
42
ShrlAlgoToolkit.RevitCore/Base/BaseCommand.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitCore.Base
|
||||
{
|
||||
public abstract class BaseCommand : IExternalCommand
|
||||
{
|
||||
// 封装常用属性,方便直接调用
|
||||
public ExternalCommandData CommandData { get; private set; }
|
||||
public UIApplication UiApplication => CommandData?.Application;
|
||||
public UIDocument UiDocument => UiApplication?.ActiveUIDocument;
|
||||
public Autodesk.Revit.ApplicationServices.Application Application => UiApplication?.Application;
|
||||
public Document Document => UiDocument?.Document;
|
||||
|
||||
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
||||
{
|
||||
CommandData = commandData;
|
||||
|
||||
try
|
||||
{
|
||||
ExecuteCommand();
|
||||
return Result.Succeeded;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return Result.Cancelled;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
message = ex.Message;
|
||||
TaskDialog.Show("Command Error", ex.ToString());
|
||||
return Result.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
// 留给具体命令去实现的核心方法
|
||||
protected abstract void ExecuteCommand();
|
||||
}
|
||||
}
|
||||
19
ShrlAlgoToolkit.RevitCore/Base/ExternalEventHelper.cs
Normal file
19
ShrlAlgoToolkit.RevitCore/Base/ExternalEventHelper.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace ShrlAlgoToolkit.RevitCore.Base
|
||||
{
|
||||
// 全局静态调用类
|
||||
public static class ExternalEventHelper
|
||||
{
|
||||
private static ActionEventHandler _handler;
|
||||
|
||||
// 在 BaseApplication 的 OnStartup 中调用
|
||||
public static void Initialize()
|
||||
{
|
||||
if (_handler == null)
|
||||
_handler = new ActionEventHandler();
|
||||
}
|
||||
|
||||
// 给 WPF 外部直接调用的入口
|
||||
public static Task InvokeAsync(Action<UIApplication> action) => _handler.RaiseAsync(action);
|
||||
public static Task<T> InvokeAsync<T>(Func<UIApplication, T> func) => _handler.RaiseAsync(func);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user