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。这个基类为更高级的封装提供了良好的起点。

相关推荐
samble14 小时前
从零搭建工业控制系统(二十二):线程安全与并发控制
c#·wpf·并发·mvvm·线程安全·工业控制
object not found15 小时前
从 Page Design 到 System Design:我对 UI/UX 的一次认知变化
ui·ux
姜穆澜15 小时前
OneID 从 0 到 1 完整生产案例(三)
大数据·wpf
xy345316 小时前
Axure9.0中继器遮罩实现方法
前端·ui·html·axure·原型·产品设计
晴天1618 小时前
Ant Design UI 库核心原理与应用
ui
dalong1018 小时前
WPF:MVVM 示例
大数据·wpf
玫瑰互动GEO21 小时前
腾讯AnswerBit(GEO优化监测平台)技术拆解:UI自动化如何采集真实AI回答
大数据·人工智能·ui·ai·自动化·geo优化
samble21 小时前
从零搭建工业控制系统(二十一):状态管理系统——中心状态对象设计
c#·wpf·mvvm·状态管理·工业控制
摸鱼仙人~1 天前
Qwen-Code ACP与AG-UI协议深度解析:区别、场景与实战报文对比
ui
mengge.cloud2 天前
存储技术基础小白教程
linux·运维·服务器·wpf·存储