当前位置: 首页 > news >正文

使用C# Channel实现工位流水线调度系统

在现代制造业中,流水线生产需要精确的工位协作。本文将介绍如何使用C#的Channel实现一个高效的工位流水线调度系统。

1、首先我们准备一个工位接口

 public interface IWorkstation{string WorkName { get; }Task StartAsync(CancellationToken cancellationToken);Task StopAsync();WorkstationStatus Status { get; }}public enum WorkstationStatus{Idle,Running,Paused,Faulted}

接着我们实现基类
基类封装了通用的启动、停止和状态管理逻辑:

  public abstract class WorkstationBase : IWorkstation, INotifyPropertyChanged{public virtual string WorkName { get; }private WorkstationStatus _status;private CancellationTokenSource _cts;private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(WorkstationBase));public WorkstationStatus Status{get => _status;protected set{_status = value;OnPropertyChanged();}}public event PropertyChangedEventHandler PropertyChanged;public async Task StartAsync(CancellationToken parentToken){if (Status == WorkstationStatus.Running)return;Status = WorkstationStatus.Running;_cts = CancellationTokenSource.CreateLinkedTokenSource(parentToken);try{await ExecuteWorkAsync(_cts.Token);}catch (OperationCanceledException){Status = WorkstationStatus.Idle;}catch (Exception ex){Status = WorkstationStatus.Faulted;// 记录错误}}public async Task StopAsync(){_cts?.Cancel();await CleanupAsync();Status = WorkstationStatus.Idle;}protected abstract Task ExecuteWorkAsync(CancellationToken token);protected virtual Task CleanupAsync() => Task.CompletedTask;protected virtual void OnPropertyChanged([CallerMemberName] string name = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));}}

我们现在可以实现流水线步骤了,假设我们的流水线只有4个工位,上料,预校,切割、下料
我们可以实现

 public class LoadWorkstation : WorkstationBase{private static long waferId = 0;public new string WorkName => "上料工位";private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(LoadWorkstation));protected override async Task ExecuteWorkAsync(CancellationToken token){while (!token.IsCancellationRequested){Logger.WriteLocal($"生成产品: {wafer.CellId}");await Task.Delay(500, token);}}}

类似的其他工位也可以这样写
接着我们启动开始按钮前需要一个Task[]来全部启动

 public class WorkstationManager{private readonly List<IWorkstation> _workstations;private CancellationTokenSource _globalCts;public IReadOnlyCollection<IWorkstation> Workstations => _workstations.AsReadOnly();public WorkstationManager(){_workstations = new List<IWorkstation>{new LoadWorkstation(),new PreWorkstation(),new CutWorkstation(),new UnLoadWorkstation(),// 其他工位...};}public async Task StartAllAsync(){await StopAllAsync();_globalCts = new CancellationTokenSource();var startTasks = _workstations.Select(ws => ws.StartAsync(_globalCts.Token));await Task.WhenAll(startTasks);}public async Task StopAllAsync(){_globalCts?.Cancel();var stopTasks = _workstations.Select(ws => ws.StopAsync());await Task.WhenAll(stopTasks);}}

我们的ViewModel对应的开始按钮可以写

 public async void ExecuteStart(){CurrentStatus = RunStatus.Running;WorkstationManager workstationManager = new WorkstationManager();await workstationManager.StartAllAsync();}

各工位独立运行,缺乏协调
产品处理顺序无法保证
无法形成真正的"流水线"
资源竞争可能导致死锁
所有的产片都是并行的,不能保证切割顺序,此时我们需要用到Channel
我们新建一个传输器的实体类,用来演示传输的数据

 public class WaferMessage{public string CellId { get; }public DateTime EnterTime { get; }public WaferMessage(string cellId){CellId = cellId;EnterTime = DateTime.Now;}}

接着使用Channel新建一个状态机

 public static class ProductionLine{// 创建工位间的通道public static readonly Channel<WaferMessage> LoadToPre = Channel.CreateUnbounded<WaferMessage>();public static readonly Channel<WaferMessage> PreToCut = Channel.CreateUnbounded<WaferMessage>();public static readonly Channel<WaferMessage> CutToUnload = Channel.CreateUnbounded<WaferMessage>();}

我们修改刚才上料的代码

 public class LoadWorkstation : WorkstationBase{private static long waferId = 0;public new string WorkName => "上料工位";private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(LoadWorkstation));protected override async Task ExecuteWorkAsync(CancellationToken token){while (!token.IsCancellationRequested){// 生成新产品,确保ID递增var id = Interlocked.Increment(ref waferId);var wafer = new WaferMessage($"Wafer-{id:D4}");Logger.WriteLocal($"生成产品: {wafer.CellId}");await Task.Delay(500, token);// 传递给预校工位await ProductionLine.LoadToPre.Writer.WriteAsync(wafer, token);Logger.WriteLocal($"{wafer.CellId} 完成上料 准备 预校");}}}

接着预校工位代码

 public class PreWorkstation : WorkstationBase{public new string WorkName => "预校工位";private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(PreWorkstation));protected override async Task ExecuteWorkAsync(CancellationToken token){while (!token.IsCancellationRequested){// 从上料工位获取产品var wafer = await ProductionLine.LoadToPre.Reader.ReadAsync(token);Logger.WriteLocal($"{wafer.CellId} 开始预校");await Task.Delay(800, token);// 传递给切割工位await ProductionLine.PreToCut.Writer.WriteAsync(wafer, token);Logger.WriteLocal($"{wafer.CellId} 完成预校 准备 切割");}}}

切割工位代码

 public class CutWorkstation : WorkstationBase{public new string WorkName => "切割工位";private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(CutWorkstation));protected override async Task ExecuteWorkAsync(CancellationToken token){while (!token.IsCancellationRequested){var wafer = await ProductionLine.PreToCut.Reader.ReadAsync(token);Logger.WriteLocal($"{wafer.CellId} 开始切割");await Task.Delay(800, token);// 传递给切割工位await ProductionLine.CutToUnload.Writer.WriteAsync(wafer, token);Logger.WriteLocal($"{wafer.CellId} 完成切割 → 下料");}}}

下料工位代码

 public class UnLoadWorkstation : WorkstationBase{private static readonly ITangdaoLogger Logger = TangdaoLogger.Get(typeof(UnLoadWorkstation));public new string WorkName => "下料工位";protected override async Task ExecuteWorkAsync(CancellationToken token){while (!token.IsCancellationRequested){var wafer = await ProductionLine.CutToUnload.Reader.ReadAsync(token);Logger.WriteLocal($"[下料] 开始: {wafer.CellId}");await Task.Delay(800, token); // 下料时间var totalTime = DateTime.Now - wafer.EnterTime;Logger.WriteLocal($"[下料] {wafer.CellId} ✓ 完成! 总耗时: {totalTime.TotalSeconds:F1}秒");}}}
http://www.rkmt.cn/news/57399.html

相关文章:

  • BLOG1-NCHU-单部电梯调度程序
  • web漏洞、waf繞過和前端加密繞過
  • 2025年水肥一体机制造厂权威推荐榜单:便携式水肥一体机/全自动喷淋系统/简易水肥一体源头厂家精选
  • Java—抽象类 - 实践
  • 英语_阅读_AI models_待读
  • 2025年食品厂生产用水紫外线消毒设备优质厂家权威推荐榜单:牛奶厂紫外线消毒设备/饮料杀菌紫外线消毒设备/啤酒生产紫外线消毒设备源头厂家精选
  • 2025年福建钨钢棒回收公司权威推荐榜单:福州钨钢合金回收/福建钨钢模具回收/福建钨钢块回收服务商精选
  • java.nio.charset.MalformedInputException: Input length = 1
  • hadoop与mysql的数据同步方法
  • 2025年上海黑臭水体修复服务权威推荐榜单:黑臭水体治理方案/河道水净化公司/河道治理服务商精选
  • LangGraph 官方教程:聊天机器人之三 - 实践
  • 2025年不锈钢管锯片供货厂家权威推荐榜单:切H型钢/角钢切割/切碳素钢锯片源头厂家精选
  • gzip linux
  • gz文件 linux
  • WPF 数据绑定通过 ElementName 失效后改为 Reference 正常
  • 2025年塑胶跑道面层环境测试舱直销厂家权威推荐榜单:塑胶跑道环境舱/2舱塑胶跑道环境舱/4舱塑胶跑道环境舱源头厂家精选
  • selenium: 找到页面上的指定元素并点击
  • 2025年sp防滑路面实力厂家权威推荐榜单:彩色防滑路面/陶瓷颗粒防滑路面/MMA彩色防滑路面源头厂家精选
  • CF359D-Pair of Numbers
  • 2025 最新支架厂家排行榜,出口级品质 + 定制服务 工程采购优选推荐电缆沟/弧形电缆沟/隧道电缆/管廊电力/角钢电缆/热镀锌角钢电缆沟支架厂家
  • 2025年AI IDE的深度评测与推荐:从单一功能效率转向生态壁垒 - 教程
  • vue3 波纹效果
  • gun linux
  • 2025年上海泰迪熊狗护理渠道权威推荐榜单:约克夏狗/西高地幼犬/可卡布犬用品及宠物店服务供应商精选
  • NCHU_单部电梯调度程序大作业
  • 2025-11-22
  • Grid-dp,交互
  • 2025 年国内电容源头厂家最新推荐排行榜:聚焦核心技术与品质,五大实力品牌选购指南电解电容/薄膜电容公司推荐
  • 初一上册CSP-J和期中考试反思
  • modbus(二)用NModbus4库实现Modbus tcp从站