public class PlcPollingScheduler{ private readonly SemaphoreSlim _semaphore; private readonly int _intervalMs; public PlcPollingScheduler(int maxConcurrency = 10, int intervalMs = 200) { _semaphore = new SemaphoreSlim(maxConcurrency); _intervalMs = intervalMs; } /// 并发轮询一组 PLC,内置变化检测和数据质量过滤 public async Task PollOnceAsync( IEnumerable<plcpoint> points, CancellationToken ct) { var tasks = points.Select(async point => { await _semaphore.WaitAsync(ct); try { double value; try { value = await point.Device.ReadAsync(point.Address, ct); } catch (Exception ex) { // 单台读取失败,记录日志,不影响其他设备 Console.WriteLine($"[读取失败] {point.Name}: {ex.Message}"); return; } // 数据质量检测(接上一篇 DataQualityChecker) var quality = point.Checker.Check(value); if (quality != DataQuality.Good) return; // 变化检测:变化超过阈值才写入 if (Math.Abs(value - point.LastValue) < point.ChangeThreshold) return; point.LastValue = value; await point.MesWriter.WriteAsync(point.Name, value); } finally { _semaphore.Release(); } }); await Task.WhenAll(tasks); } /// 持续轮询循环 public async Task RunAsync( IEnumerable<plcpoint> points, CancellationToken ct) { while (!ct.IsCancellationRequested) { var sw = Stopwatch.StartNew(); await PollOnceAsync(points, ct); sw.Stop(); // 扣除已花时间,保证轮询间隔稳定 var remaining = _intervalMs - (int)sw.ElapsedMilliseconds; if (remaining > 0) await Task.Delay(remaining, ct) .ContinueWith(_ => { }); } }}// 使用:三组分级,各自独立跑var highScheduler = new PlcPollingScheduler(maxConcurrency: 10, intervalMs: 100);var midScheduler = new PlcPollingScheduler(maxConcurrency: 10, intervalMs: 500);var lowScheduler = new PlcPollingScheduler(maxConcurrency: 5, intervalMs: 5000);_ = highScheduler.RunAsync(highPriorityPoints, ct);_ = midScheduler.RunAsync(midPriorityPoints, ct);_ = lowScheduler.RunAsync(lowPriorityPoints, ct);
---
三个方法组合的实际效果
20 台 PLC,优化前延迟稳定在 3 秒以上。加了并发轮询、分级采集、变化过滤三层之后:
并发轮询:3.2s → ~200ms分级采集:轮询总压力下降 ~70%变化过滤:MES 写入量下降 ~60%最终延迟:稳定在 150ms ~ 300ms 采集慢,不是因为你写得慢。而是你还在用串行思维解决并发问题。模型换了,延迟自然就下去了。 你的分享、点赞、在看、我都喜欢
转发是最大的鼓励!谢谢您的支持!
想加入电气工控自动化技术交流群
请添加班长为好友
(文章来源:工业软件架构笔记)
</plcpoint></plcpoint>
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!