public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer, int limit) { if (cache == null || addrArr == null || buffer == null || addrArr.Length != buffer.Length) { return(-1); } if (addrArr.Length == 1) { return(plc.WriteValue(addrArr[0], buffer[0])); } lock (plc) //不锁定会有并发冲突问题;锁定也不能保障绝对安全,如有人现场操作会导致数据刷新 { List <PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrArr); int offset = 0; foreach (PDUArea area in areas) { byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); if (rcvBytes == null) { return(-1); } Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); offset += rcvBytes.Length / cache.ByteCount; } DeviceAddress start = addrArr[0]; int startIndex = 0; int endIndex = 0; while (endIndex < addrArr.Length) { if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber || endIndex - startIndex >= limit) { for (int i = startIndex; i < endIndex; i++) { cache.WriteValue(addrArr[i], buffer[i]); } int c1 = start.CacheIndex; int c2 = addrArr[endIndex - 1].CacheIndex; byte[] bytes = new byte[cache.ByteCount * (c2 - c1 + 1)]; Buffer.BlockCopy(cache.Cache, c1, bytes, 0, bytes.Length); if (plc.WriteBytes(start, bytes) < 0) { return(-1); } start = addrArr[endIndex]; startIndex = endIndex; } endIndex++; } } return(0); }