1.为啥板卡要继承 public abstract class CardControlBase : IDisposable回收这个接口C#不是自己内部会有回收机制吗答垃圾回收只回收托管内存不管硬件句柄、文件、网络连接这类资源而且回收时机不确定。IDisposable 是让你立刻、确定地关掉这些资源的约定。Close() → ImplementCloseCard()关掉板卡。GC 不知道这块卡还开着也不会去关它。对象被回收时板卡可能仍然占着驱动和总线。把事件置空订阅者会把这个对象留在内存里。不手动摘掉GC 可能一直收不掉它。时机GC 什么时候跑由运行时决定可能是几秒后也可能是进程退出时。控制卡必须在你指定的时刻关闭不能等“以后某次回收”。2.板卡读取IO后的方法对于输入可以写一个线程一直读取所有的输入信号(下面代码是读取IO的算法)读取以后同意保存在一个变量里线程里面还有一个方法判断输出是否需要动作这里会有一个变量当刷新时间到达当外界有输出这个变量就会设为true需要的话再次读取输出的状态同意保存在另一个变量里面。public bool GetModbusOutCache(int InAddress) { if (CacheReadOut null) return false; if ((DateTime.Now - dateTime_OutUpdate).TotalMilliseconds 100) { isNeedUpdateOut true; for (int i 0; i 100; i) { Thread.Sleep(10); if (isNeedUpdateOut false) break; } } var indexStart (InAddress - MinStartAddress) / 8; var m (InAddress - MinStartAddress) % 8; return (CacheReadOut[indexStart] (1 m)) 0; } public override int Out_GetAll(IntPtr g_handle) { int piValue 0; for (int i 0; i OutTotalNums; i) { if (CacheModule.GetModbusOutCache(StartAddress i)) { piValue (piValue ^ 1 i); } } return piValue; } public override int In_GetAll(IntPtr g_handle) { int piValue 0; for (int i 0; i InTotalNums; i) { if (CacheModule.GetModbusInCache(StartAddress i)) { piValue (piValue ^ 1 i); } } return piValue; } public override bool In_Getbit(IntPtr g_handle, short bitNo) { return CacheModule.GetModbusInCache(StartAddress bitNo); } public override bool Out_Getbit(IntPtr g_handle, short bitNo) { return CacheModule.GetModbusOutCache(StartAddress bitNo); }