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

相关推荐
wuyk55514 小时前
PyQt6-第05讲-QtDesigner工作流与ui文件
python·ui·pyqt
Meta Luo15 小时前
UI 自动化测试中的等待、超时和异步加载怎么处理
功能测试·测试工具·ui·回归·自动化
Light Gao17 小时前
AI 对话助手如何实现动态交互?一文讲清 AG-UI、SSE、组件与工具调用
人工智能·ui·交互·大语言模型·sse·智能体·ag-ui
MicrosoftReactor20 小时前
技术速递|当聊天框不再是合适的交互界面
ui·ai·copilot·canvas
秋名山小白1 天前
UI自动化-Airtest框架落地实战
运维·ui·自动化
donk13141 天前
React Native for OpenHarmony 实战:三方库 react-native-circular-action-menu 的鸿蒙化适配指南
javascript·分布式·react native·react.js·wpf·harmonyos
const_qiu1 天前
第 2.5 章 2.5.8:质量关 —— 安全审查、UI/UX 审查与踩坑复盘
java·人工智能·安全·ui·ux
Autumn_ing1 天前
Design.md生成UI怎么验收?举例运营后台的颜色、状态和数据核对
前端·ui·ai·设计系统·paico·ai生成ui·design.md
特立独行的猫a2 天前
仓颉语言UI开发实战:我用仓颉写了个桌面版力扣
算法·leetcode·ui·tauri·仓颉·cj-tarui
Wang's Blog2 天前
Java 项目实战: 交友项目 - JWT 概述:为什么要用 Token 换掉 Session
java·ui·交友