1.代码部分
UI XAML部分:
<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>
XAML.CS
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();
}
}
}
全局业务流程接口:ICommonInterFace
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);
}
}
流程控制器(调度中心):FlowController
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;
}
}
}
}
配方参数配置Model类:
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; }
}
}
业务类1:Func1
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();
}
}
}
业务类2:Func2
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();
}
}
}
业务类3:Func3
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();
}
}
}