WPF UI标准流水线

复制代码
流水线基类
cs 复制代码
    public class ViewModelBase : INotifyPropertyChanged
    {
        protected readonly TaskScheduler _uiScheduler;

        public ViewModelBase()
        {
            _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// UI标准流水线:捕获状态→后台任务→更新UI→恢复状态
        /// </summary>
        protected void ExecuteWithUiPipeline<TState, TResult>(
            Func<TState> captureState,
            Func<TState, TResult> backgroundWork,
            Action<TResult> updateUi,
            Action<TState> restoreUi,
            Action<bool> busyFlagSetter)
        {
            busyFlagSetter(true);
            var state = captureState();

            Task.Factory.StartNew(() => backgroundWork(state))
            .ContinueWith(task =>
            {
                try
                {
                    if (task.Exception != null)
                    {
                        var ex = task.Exception.InnerException ?? task.Exception;
                        MessageBox.Show("操作异常:" + ex.Message);
                        return;
                    }
                    var result = task.Result;
                    updateUi(result);
                    restoreUi(state);
                }
                finally
                {
                    busyFlagSetter(false);
                }
            }, _uiScheduler);
        }
    }

子类使用示例

cs 复制代码
public class TreeViewModel : ViewModelBase
{
    private bool _isBusy;
    public bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged(nameof(IsBusy)); } }

    public void RefreshTree()
    {
        // 定义捕获状态
        Func<TreeState> capture = () => new TreeState
        {
            SelectedId = FindSelectedNode(TreeRoot)?.Id ?? -1,
            ExpandedIds = GetExpandedIds(TreeRoot)
        };

        // 后台工作
        Func<TreeState, List<NodeModel>> work = state => LoadDataFromDb();

        // 更新UI
        Action<List<NodeModel>> update = data =>
        {
            TreeRoot = new ObservableCollection<NodeViewModel>(BuildTree(data));
        };

        // 恢复状态
        Action<TreeState> restore = state =>
        {
            RestoreState(TreeRoot, state.SelectedId, state.ExpandedIds);
        };

        // 执行流水线
        ExecuteWithUiPipeline(capture, work, update, restore, busy => IsBusy = busy);
    }
}

🧠 总结

ViewModelBase 提供的这个流水线方法,本质上是将WPF异步编程中反复出现的"线程切换 + 状态管理"模式抽象为一个可复用的基础设施。它让子类代码更简洁、更聚焦于业务,同时保证了UI线程安全。你只需要在子类中实现具体的状态捕获、后台任务和UI恢复逻辑,框架自动帮你处理调度和异常。

如果你还想加入防重入版本号 功能,可以在子类中扩展,或者在ExecuteWithUiPipeline的基础上再封装一层,传入一个Func<bool>检查是否可以执行,或者集成CancellationToken。这个基类为更高级的封装提供了良好的起点。

相关推荐
心平气和量大福大15 小时前
C#-WPF-控件-LiveChart图表-线性2(LineSeries)-数据绑定
开发语言·c#·wpf
绿浪198415 小时前
WPF 防重入,时序错乱详解
wpf
向夏威夷 梦断明暄2 天前
【GUI-Agent】阿里通义MAI-UI 代码阅读(2)--- 实现
ui
whn19772 天前
oracle的节点2无法启动asm实例 提示PMON terminating the instance due to error 481
数据库·oracle·wpf
完美火龙篇 四月的友2 天前
WPF 笔迹延迟优化从硬件到软件的全链路分析
wpf
dalong102 天前
WPF:3D立方体
3d·wpf
icestone20002 天前
彻底解决 RDP 断开后 UI 自动化(RPA)失效问题:三步让机器人后台无缝运行
ui·自动化·rpa
Kim.Li2 天前
格式塔设计原则全解析:12项核心原则在 UI/UX 中的实战应用指南
ui·产品经理·ux·视觉设计·交互设计
jin1233223 天前
HarmonyOS ArkTS API 24实现声明式 UI 框架与 @Builder 组件复用模式构建三标签页智能账单应用
ui·华为·harmonyos