From c2bcdeac206a399fba6a5462900fc08f4b900e8f Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Wed, 24 May 2017 14:52:13 +0800 Subject: [PATCH] Bug Fix --- Modbus.Net/src/Base.Common/TaskManager.cs | 58 ++++++++++++++++------- Tests/Modbus.Net.Tests/TaskManagerTest.cs | 40 +++++++--------- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/Modbus.Net/src/Base.Common/TaskManager.cs b/Modbus.Net/src/Base.Common/TaskManager.cs index b1d5d6c..49a7b5d 100644 --- a/Modbus.Net/src/Base.Common/TaskManager.cs +++ b/Modbus.Net/src/Base.Common/TaskManager.cs @@ -352,13 +352,9 @@ namespace Modbus.Net /// 任务是否执行成功 public async Task InvokeOnce(TaskItem task) { - if (Machine.IsConnected) - { - var ans = await task.Invoke(Machine, _tasks, task.Params, task.TimeoutTime); - task.Return?.Invoke(ans); - return true; - } - return false; + var ans = await task.Invoke(Machine, _tasks, task.Params?.Invoke(), task.TimeoutTime); + task.Return?.Invoke(ans); + return true; } } @@ -409,10 +405,8 @@ namespace Modbus.Net /// /// 返回值的处理函数 /// 返回值的键类型 - /// 循环间隔(毫秒) - /// 设备离线时的循环间隔(毫秒) /// 任务的超时时间 - public TaskItemGetData(Action returnFunc, MachineGetDataType getDataType, int getCycle, int sleepCycle, int timeout = 100000) + public TaskItemGetData(Action returnFunc, MachineGetDataType getDataType, int timeout = 100000) { Name = "GetDatas"; TimeoutTime = timeout; @@ -433,6 +427,19 @@ namespace Modbus.Net }; Params = null; Return = returnFunc; + } + + /// + /// 构造函数 + /// + /// 返回值的处理函数 + /// 返回值的键类型 + /// 循环间隔(毫秒) + /// 设备离线时的循环间隔(毫秒) + /// 任务的超时时间 + public TaskItemGetData(Action returnFunc, MachineGetDataType getDataType, int getCycle, + int sleepCycle, int timeout = 100000) : this(returnFunc, getDataType, timeout) + { TimerDisconnectedTime = sleepCycle; TimerTime = getCycle; } @@ -450,24 +457,41 @@ namespace Modbus.Net /// 写入值的键类型 /// 返回值的处理函数 /// 任务的超时时间 - public TaskItemSetData(Dictionary values, MachineSetDataType setDataType, Action returnFunc = null, int timeout = 100000) + public TaskItemSetData(Func> values, MachineSetDataType setDataType, int timeout = 100000, Action returnFunc = null) { Name = "SetDatas"; TimeoutTime = timeout; - Invoke = Invoke = async (machine, tasks, parameters, timeoutTime) => + Invoke = async (machine, tasks, parameters, timeoutTime) => { var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromMilliseconds(timeoutTime)); var ans = await tasks.StartNew( async () => await machine.InvokeMachineMethod>("SetDatasAsync", parameters[0], - setDataType).WithCancellation(cts.Token)).Unwrap(); + Task>("SetDatasAsync", setDataType, parameters[0] + ).WithCancellation(cts.Token)).Unwrap(); return ans; }; - Params = new object[] {values}; + Params = () => new object[] {values()}; Return = returnFunc; } + + /// + /// 构造函数 + /// + /// 写入的值 + /// 写入值的键类型 + /// 返回值的处理函数 + /// 循环间隔(毫秒) + /// 设备离线时的循环间隔(毫秒) + /// 任务的超时时间 + public TaskItemSetData(Func> values, MachineSetDataType setDataType, int getCycle, + int sleepCycle, int timeout = 100000, Action returnFunc = null) + : this(values, setDataType, timeout, returnFunc) + { + TimerDisconnectedTime = sleepCycle; + TimerTime = getCycle; + } } /// @@ -514,7 +538,7 @@ namespace Modbus.Net /// /// 任务执行的参数 /// - public object[] Params { get; set; } + public Func Params { get; set; } /// /// 返回值的处理函数 @@ -575,7 +599,7 @@ namespace Modbus.Net Timer = new Timer(async state => { if (!DetectConnected()) TimerChangeToDisconnect(); - var ans = await Invoke(GetMachine(), GetTaskFactory(), Params, TimeoutTime); + var ans = await Invoke(GetMachine(), GetTaskFactory(), Params?.Invoke(), TimeoutTime); Return?.Invoke(ans); }, null, 0, TimerTime); } diff --git a/Tests/Modbus.Net.Tests/TaskManagerTest.cs b/Tests/Modbus.Net.Tests/TaskManagerTest.cs index fe65059..9c889be 100644 --- a/Tests/Modbus.Net.Tests/TaskManagerTest.cs +++ b/Tests/Modbus.Net.Tests/TaskManagerTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Modbus.Net.Modbus; @@ -79,13 +80,16 @@ namespace Modbus.Net.Tests } }; - BaseMachine machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.10", addresses, true, 2, 0); + BaseMachine machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.10", addresses, true, 2, 0) + { + Id = "1" + }; _taskManager.AddMachine(machine); var r = new Random(); - _timer = new Timer(state => + _timer = new Timer(async state => { lock (_valueDic) { @@ -111,43 +115,31 @@ namespace Modbus.Net.Tests } }; } - }, null, 0, 1000); - - _taskManager.InvokeTimerAll(new TaskItemSetData(_valueDic, MachineSetDataType.CommunicationTag) - { - TimerTime = 2000, - TimeoutTime = 60000, - TimerDisconnectedTime = 10000 - }); + await _taskManager.InvokeOnceAll(new TaskItemSetData(() => _valueDic, MachineSetDataType.CommunicationTag)); + }, null, 0, 5000); } [TestMethod] - public void TaskManagerValueReadWriteTest() + public async Task TaskManagerValueReadWriteTest() { - var dicans = new Dictionary(); - _taskManager.InvokeTimerAll(new TaskItemGetData( - def => - { - dicans = def.ReturnValues.ToDictionary(p => p.Key, p => p.Value.PlcValue); - }, MachineGetDataType.CommunicationTag, 2000, 10000, 60000)); + Thread.Sleep(2000); var i = 5; while (i > 0) { - Thread.Sleep(10000); - lock (dicans) - { - lock (_valueDic) + Thread.Sleep(5000); + await _taskManager.InvokeOnceAll(new TaskItemGetData( + def => { + var dicans = def.ReturnValues.ToDictionary(p => p.Key, p => p.Value.PlcValue); Assert.AreEqual(dicans["A1"], _valueDic["A1"]); Assert.AreEqual(dicans["A2"], _valueDic["A2"]); Assert.AreEqual(dicans["A3"], _valueDic["A3"]); Assert.AreEqual(dicans["A4"], _valueDic["A4"]); Assert.AreEqual(dicans["A5"], _valueDic["A5"]); Assert.AreEqual(dicans["A6"], _valueDic["A6"]); - } - } - i--; + }, MachineGetDataType.CommunicationTag)); + i--; } }