勇哥注:
我们继续上一篇《C# 勇哥关于多线程读写plc内存的研究续,引用ReaderWriterLockSlim锁带来的读操作并发的问题》
此系列贴子已经写了好几篇了:
(4)C# 勇哥关于多线程读写plc内存的研究续,引用ReaderWriterLockSlim锁带来的读操作并发的问题
(3)C# 勇哥关于多线程读写plc内存的研究续,解决UI控件读写的效率问题
(2)C# 勇哥关于多线程读写plc内存的研究续,解决lock锁的效率问题
(1) C# 勇哥关于多线程读写plc内存的研究
上一篇末尾的问题:
跑了一晚上后,发现只有最后一个地址的数值(13414)在跳动,其它的都不动,应该是死掉了。
首先勇哥检查了plc的内存,发现头三个地址的值确实没有更新了,只有最后一个地址的值在变化。
这说明“启动4个读线程”没有问题,并不是因为它们死掉了所以ui上刷新不了。
再看下其中一个写线程的代码:
PlcReadWrite plc = null; Random ran = null; Task.Factory.StartNew(() => { Stopwatch sw1 = new Stopwatch(); sw1.Start(); short j1 = 0; while (!rndStop) { plc = new PlcReadWrite(); ++j1; plc.Write(0,j1, Guid.NewGuid()); while(true) { if(sw1.ElapsedMilliseconds>1000) { sw1.Restart();break; } Thread.Sleep(10); } } });
首先那个j1是个short,最大值为32767,所以并不是因为j1溢出了。
由数值6717来看,第一个地址写内存是每隔1秒写一次,也就不到2小时,上面的代码就死掉再不工作了。
地址1--地址4,依次是隔1, 2, 3, 4秒写入
但是最后一个地址值反而最大,这让人怀疑是否写入混乱了。
我们干脆加把锁,让4个写入无可能同时写入。(虽然4个时序按时序来讲好像是不能同时写入的)
这个锁定义如下:
private static readonly object writeLock = new object();
只需要lock到Write函数里就行了。
现在这个函数就有两把锁了。
/// <summary> /// 写plc内存 /// </summary> /// <param name="addr">plc内存地址,填写相对地址,从0开始</param> /// <param name="data">写入的数据,short类型</param> /// <param name="_id">guid</param> /// <returns></returns> public int Write(int addr,short data, Guid _id) { lock (writeLock) { rwlock.EnterWriteLock(); { try { var writeSw = new Stopwatch(); writeSw.Start(); isRead = false; WriteCmdList.Add(new WriteCmd() { addr = addr, id = _id, writeData = data, writeStatus = -1 }); var idx = -1; int js1 = 0; while (true) { if (writeSw.ElapsedMilliseconds > 2000) { //读plc超时 writeSw.Stop(); return -1; } if (sw2.ElapsedMilliseconds > 50 && js1 == 0) { //通知写plc mr[0].Set(); sw2.Restart(); ++js1; } idx = WriteCmdList.FindIndex(s => s.id == _id && s.writeStatus == 1); if (idx >= 0) { //写成功了,返回1 WriteCmdList.RemoveAt(idx); plclog.AddLog(new logdata() { id = _id, readOrWrite = readwriteEnum.write, plcAddr = (short)addr, recTime = DateTime.Now, itemCount = WriteCmdList.Count }); return 1; } Thread.Sleep(1); } } finally { rwlock.ExitWriteLock(); } } } }
由于至少要测试2小时以上才可能看到结果。
就留今天晚上跑通宵吧。
未完待续。。。。
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

