2026产品管理系统横向测评:八款主流工具选型对比与避坑指南
2026/9/21 6:59:16
<Window x:Class="FlowControl20260829.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:FlowControl20260829" mc:Ignorable="d" Loaded="Window_Loaded" Title="MainWindow" Height="450" Width="800"> <Grid> <Button Content="BtnRun_Click" HorizontalAlignment="Left" Margin="320,95,0,0" Click="BtnRun_Click" VerticalAlignment="Top" Width="96" Height="40"/> <Button Content="BtnPause_Click" HorizontalAlignment="Left" Margin="320,163,0,0" Click="BtnPause_Click" VerticalAlignment="Top" Width="96" Height="37"/> <Button Content="BtnStop_Click" HorizontalAlignment="Left" Margin="320,232,0,0" Click="BtnStop_Click" VerticalAlignment="Top" Width="96" Height="43"/> <Button Content="BtnLoadScript_Click" HorizontalAlignment="Left" Margin="320,35,0,0" Click="BtnLoadScript_Click" VerticalAlignment="Top" Width="96" Height="35"/> </Grid> </Window>using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace FlowControl20260829 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private const string NameSpace = "FlowControl20260829"; //全流程控制部分 private readonly FlowController _controller = new FlowController(); //====调度控制信号==== private CancellationTokenSource _cts; private bool _isPause; private readonly object _pauseLock = new object(); private bool _isRunning; // 缓存已经创建好的业务实例列表(加载一次,反复执行) private List<ICommonInterFace> _cachedTaskList = new List<ICommonInterFace>(); private void Window_Loaded(object sender, RoutedEventArgs e) { //FlowController controller = new FlowController(); //controller.RunFlow(new Func1()); //controller.RunFlow(new Func2()); //controller.RunFlow(new Func3()); //Console.WriteLine("最终完成"); } List<FlowModel> listFlowModel; List<string> taskOrder; /// <summary> /// 将任务顺序保存成文本文档 /// </summary> private void SaveTaskListToTxt() { // 这里就是你想要执行的任务序列,可由界面UI勾选/拖拽修改这个列表 List<string> taskOrder = new List<string>() { "Func1", "Func3", "Func2", "Func3" }; } //private async void BtnRun_Click(object sender, RoutedEventArgs e) //{ // if (_isRunning) // { // Console.WriteLine("⚠️流程正在运行,请勿重复点击"); // return; // } // _cts = new CancellationTokenSource(); // _isPause = false; // _isRunning = true; // try // { // await RunScriptAsync(_cts.Token); // } // catch (OperationCanceledException) // { // Console.WriteLine("🛑流程已被手动停止"); // } // catch (Exception ex) // { // Console.WriteLine($"❌流程全局异常:{ex.Message}"); // } // finally // { // _isRunning = false; // _cts?.Dispose(); // _cts = null; // Console.WriteLine("====流程结束===="); // } //} ///// <summary> ///// 你原来核心逻辑,升级带暂停停止 ///// </summary> //private async Task RunScriptAsync(CancellationToken token)//原 //{ // //var lines = File.ReadAllLines("runScript.txt"); // List<string> taskOrder = new List<string>() // { // "Func1", // "Func3", // "Func2", // "Func3" // }; // var lines = taskOrder; // foreach (var line in lines) // { // //检查是否按下停止 // token.ThrowIfCancellationRequested(); // string className = line.Trim(); // if (string.IsNullOrEmpty(className)) continue; // //=====暂停循环===== // while (true) // { // lock (_pauseLock) // { // if (!_isPause) break; // } // //暂停时每隔100ms轮询一次 // await Task.Delay(100, token); // } // string fullTypeName = $"{NameSpace}.{className}"; // Type type = Type.GetType(fullTypeName); // if (type == null) // { // Console.WriteLine($"找不到类:{className},跳过"); // continue; // } // if (!typeof(ICommonInterFace).IsAssignableFrom(type)) // { // Console.WriteLine($"{className} 没有实现IBusinessFlow接口"); // continue; // } // ICommonInterFace flow; // try // { // flow = (ICommonInterFace)Activator.CreateInstance(type); // } // catch (Exception ex) // { // Console.WriteLine($"实例化 {className} 失败:{ex.Message}"); // continue; // } // //后台执行业务,不卡住UI界面 // await Task.Run(() => // { // token.ThrowIfCancellationRequested(); // _controller.RunFlow(flow); // }, token); // await Task.Delay(300, token); // } // Console.WriteLine("✅脚本全部完成"); //} /// <summary> /// 【运行按钮】直接执行缓存好的实例,不再读文件、不再反射 /// </summary> private async void BtnRun_Click(object sender, RoutedEventArgs e) { if (_isRunning) { Console.WriteLine("⚠️流程正在运行"); return; } if (_cachedTaskList.Count == 0) { Console.WriteLine("⚠️还没有加载任何脚本任务,请先加载脚本"); return; } _cts = new CancellationTokenSource(); _isPause = false; _isRunning = true; try { await RunCachedTasksAsync(_cts.Token); } catch (OperationCanceledException) { Console.WriteLine("🛑流程已被手动停止"); } catch (Exception ex) { Console.WriteLine($"❌全局异常:{ex.Message}"); } finally { _isRunning = false; _cts?.Dispose(); _cts = null; Console.WriteLine("====流程执行结束===\r\n"); } } /// <summary> /// 遍历缓存列表执行业务 /// </summary> private async Task RunCachedTasksAsync(CancellationToken token) { foreach (var flow in _cachedTaskList) { token.ThrowIfCancellationRequested(); //暂停等待循环 while (true) { lock (_pauseLock) { if (!_isPause) break; } await Task.Delay(100, token); } try { await Task.Run(() => { token.ThrowIfCancellationRequested(); _controller.RunFlow(flow); }, token); } catch (Exception ex) { Console.WriteLine($"❌执行业务出错:{ex.Message}"); // 出错继续往下执行,如需报错即停止解开下面注释 // throw; } await Task.Delay(300, token); } Console.WriteLine("✅缓存内所有任务执行完毕"); } //缓存配置列表(只存脚本配置,每次运行新建业务实例) private List<FlowModel> _cachedFlowList = new List<FlowModel>(); /// <summary> /// 【加载脚本按钮】读取txt,一次性创建全部实例存入缓存 /// </summary> private void BtnLoadScript_Click(object sender, RoutedEventArgs e) { //先清空旧缓存 _cachedTaskList.Clear(); //var lines = File.ReadAllLines(filePath); List<string> taskOrder = new List<string>() { "Func1", "Func3", "Func2", "Func3" }; var lines = taskOrder; //json文件数据加载 string jsonPath = "runScript.json"; string fullPath = System.IO.Path.GetFullPath(jsonPath); Console.WriteLine($"正在加载脚本路径:{fullPath}"); if (!File.Exists(jsonPath)) { Console.WriteLine("❌ JSON脚本文件不存在"); return; } try { string jsonText = File.ReadAllText(jsonPath); JsonSerializerOptions opt = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }; _cachedFlowList = JsonSerializer.Deserialize<List<FlowModel>>(jsonText, opt); if (_cachedFlowList == null) _cachedFlowList = new List<FlowModel>(); Console.WriteLine($"✅ JSON加载完成,共读取 {_cachedFlowList.Count} 条任务"); foreach (var item in _cachedFlowList) { Console.WriteLine($" 任务:{item.MethodName} 参数:{item.MethodPara}"); } } catch (Exception ex) { Console.WriteLine($"❌ JSON解析失败:{ex.Message}"); } //foreach (var line in lines) foreach (var line in _cachedFlowList) { //string className = line.Trim(); string className = line.MethodName.Trim(); if (string.IsNullOrEmpty(className)) continue; string fullTypeName = $"{NameSpace}.{className}"; Type type = Type.GetType(fullTypeName); if (type == null) { Console.WriteLine($"⚠️找不到类:{className},跳过"); continue; } if (!typeof(ICommonInterFace).IsAssignableFrom(type)) { Console.WriteLine($"⚠️ {className} 未实现IBusinessFlow接口,跳过"); continue; } try { //一次性new实例 ICommonInterFace flow = (ICommonInterFace)Activator.CreateInstance(type); flow.SetParameter(line); _cachedTaskList.Add(flow); Console.WriteLine($"✅成功加载任务:{className}"); } catch (Exception ex) { Console.WriteLine($"❌实例化失败 {className}:{ex.Message}"); } } Console.WriteLine($"\n脚本加载完成,共载入 {_cachedTaskList.Count} 个任务\r\n"); } //暂停按钮 private void BtnPause_Click(object sender, RoutedEventArgs e) { if (!_isRunning) return; lock (_pauseLock) { _isPause = !_isPause; } Console.WriteLine(_isPause ? "⏸已暂停" : "▶继续运行"); } //停止按钮 private void BtnStop_Click(object sender, RoutedEventArgs e) { if (!_isRunning) return; _cts?.Cancel(); } } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { //public class CommonInterFace //{ //} // 1.公共接口:所有业务都要实现这个流程 public interface ICommonInterFace { /// 执行业务流程 bool Execute( ); /// <summary>灌入整条配置模型,子类自行解析所有参数</summary> void SetParameter(FlowModel flowModel); } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { // 5.流程控制器(调度中心) public class FlowController { // 接收任意实现接口的业务对象,统一运行 public bool RunFlow(ICommonInterFace business) { try { return business.Execute( ); } catch (Exception ex) { return false; } } } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { public class FlowModel { /// <summary>业务类名,反射查找用</summary> public string MethodName { get; set; } /// <summary>通用参数,简单值可以放这里</summary> public object MethodPara { get; set; } //====以后新增任何参数直接往下加,接口不用改!==== //public int Timeout { get; set; } //public double XPos { get; set; } //public double YPos { get; set; } //public bool Enable { get; set; } } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { public class Func1 : ICommonInterFace { int int1= 0; public bool Execute( ) { Method1(int1); //Console.WriteLine("【业务1】完成"); return true; } public void Method1(int intPara) { Console.WriteLine($"【业务1】完成,携带Int数据{intPara}"); } public void SetParameter(FlowModel para) { int1 =int.Parse(para.MethodPara.ToString()); //throw new NotImplementedException(); } } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { public class Func2 : ICommonInterFace { string strPara = "Func2"; public bool Execute() { Method2(strPara); //Console.WriteLine("【业务2】完成"); return true; } public void Method2(string strPara) { Console.WriteLine($"【业务2】完成,携带String数据{strPara}"); } public void SetParameter(FlowModel para) { strPara = para.MethodPara.ToString(); //throw new NotImplementedException(); } } }using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FlowControl20260829 { public class Func3 : ICommonInterFace { public bool Execute( ) { Method3(); //Console.WriteLine("【业务3】完成"); return true; } public void Method3() { Console.WriteLine("【业务3】完成"); } public void SetParameter(FlowModel para) { //throw new NotImplementedException(); } } }