清理ColorPicker,进度条。修复UI问题
This commit is contained in:
74
ShrlAlgo.Addin.Test/ProgressManager.cs
Normal file
74
ShrlAlgo.Addin.Test/ProgressManager.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace ShrlAlgo.Addin.Test
|
||||
{
|
||||
public static class ProgressManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动带进度条的 Revit 主线程任务
|
||||
/// </summary>
|
||||
/// <param name="title">进度条窗口标题</param>
|
||||
/// <param name="revitTask">需要在 Revit 主线程执行的任务逻辑</param>
|
||||
public static void Run(string title, Action<ProgressReporter, CancellationToken> revitTask)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
var viewModel = new ProgressViewModel(title, cts);
|
||||
var reporter = new ProgressReporter(viewModel);
|
||||
|
||||
// 使用 ManualResetEvent 等待 WPF 窗口初始化完成
|
||||
using (var viewReadyEvent = new ManualResetEvent(false))
|
||||
{
|
||||
// 1. 创建独立的 STA 线程运行 WPF UI
|
||||
var uiThread = new Thread(() =>
|
||||
{
|
||||
viewModel.UIDispatcher = Dispatcher.CurrentDispatcher;
|
||||
var window = new ProgressWindow(viewModel);
|
||||
window.Show();
|
||||
|
||||
viewReadyEvent.Set(); // 通知主线程 UI 已就绪
|
||||
|
||||
Dispatcher.Run(); // 开启消息循环
|
||||
});
|
||||
|
||||
uiThread.SetApartmentState(ApartmentState.STA); // 必须是 STA
|
||||
uiThread.IsBackground = true;
|
||||
uiThread.Start();
|
||||
|
||||
viewReadyEvent.WaitOne(); // 阻塞主线程,直到 WPF 窗体显示
|
||||
|
||||
// 2. 在 Revit 主线程中执行耗时任务
|
||||
try
|
||||
{
|
||||
revitTask(reporter, cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 捕获取消异常,静默处理即可
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Autodesk.Revit.UI.TaskDialog.Show("Task Error", ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 3. 任务结束,通知 WPF 线程关闭窗口并停止调度器
|
||||
if (viewModel.UIDispatcher != null && !viewModel.UIDispatcher.HasShutdownStarted)
|
||||
{
|
||||
viewModel.UIDispatcher.InvokeAsync(() =>
|
||||
{
|
||||
viewModel.CloseAction?.Invoke();
|
||||
Dispatcher.CurrentDispatcher.InvokeShutdown();
|
||||
});
|
||||
}
|
||||
uiThread.Join(1000); // 等待 UI 线程彻底退出
|
||||
cts.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user