数据入队模块的-ExeModule
DataIn.ExeModule()方法解析这个方法与刚才的 DataOut 是配对的——DataIn 是生产者往队列写数据DataOut 是消费者从队列读数据。对照着看会更容易理解。1. 确保队列存在懒创建if(!Solution.Ins.QueueDic.ContainsKey(QueueKey))Solution.Ins.QueueDic[QueueKey]newJGTechVision.Services.DataOut(QueueKey);和 DataOut 不同DataIn不要求队列事先存在——如果全局字典里没有这个 key就直接创建一个。这样无论哪个模块先运行队列都能正常工作。2. 定义槽位结构只做一次if(!_slotsDefined){DefineAllSlots(outQueue);// 根据每个槽位的DataType创建对应的Listdouble/int/string/bool_slotsDefinedtrue;}DefineAllSlots遍历所有启用的槽位根据数据类型调用outQueue.DefineDoubleQueue()/DefineIntQueue()等在队列内部初始化对应的ListT。这个操作只执行一次_slotsDefined标志防止重复定义。3. 从上游取数据写入队列lock(outQueue){foreach(varslotinQueueSlots.Where(ss.IsEnable)){objectvalGetLinkValue(slot.LinkVar.Text);// 从上游模块获取值if(valnull)continue;intidxslot.SlotIndex;switch(slot.DataType){casedouble:vardList(Listdouble)outQueue.GetDataQueue(idx);if(dList.CountoutQueue.LimitLength)dList.RemoveAt(0);// 满了就丢掉最旧的dList.Add(Convert.ToDouble(val));break;// ... int / string / bool 同理}}}这里的核心逻辑GetLinkValue(slot.LinkVar.Text)LinkVar.Text存的是类似模块名.变量名的引用字符串GetLinkValue通过这个引用去上游模块拿到实际值。这是框架的变量链接机制——相当于画一条线把上游模块的输出接到本模块的输入。环形缓冲区ring bufferif (dList.Count outQueue.LimitLength) dList.RemoveAt(0)—— 如果队列已满达到LimitLength上限就丢掉最旧的那条数据索引0然后追加新数据。这保证了队列不会无限增长。4. 唤醒消费者关键一步if(Solution.Ins.QueueSignDic.ContainsKey(QueueKey))Solution.Ins.QueueSignDic[QueueKey].Set();这就是和 DataOut 的signal.WaitOne(TimeOut)配对的地方。DataIn 写完数据后调用Set()把信号量置为有信号状态这会唤醒正在WaitOne阻塞等待的 DataOut 线程让它立刻去读取数据。DataIn vs DataOut 对照DataIn入队/生产者DataOut出队/消费者方向从上游模块拿值 → 写入队列从队列取值 → 暴露为输出参数数据来源GetLinkValue(LinkVar.Text)变量链接GetSlotValue(outQueue, slot)从队列读队列满时RemoveAt(0)丢弃最旧数据不适用只读队列空时不关心根据IsWait决定阻塞等待还是报错信号量signal.Set()唤醒对方signal.WaitOne(TimeOut)等待被唤醒队列不存在时自动创建报错返回一句话总结DataIn 的ExeModule是一个带环形缓冲的生产者它从上游模块通过变量链接拿到数据按槽位和类型写入全局队列写完后发信号唤醒等待中的 DataOut 消费者。队列满时自动丢弃最旧数据防止内存无限增长。