This commit is contained in:
parallelbgls
2017-05-24 14:52:13 +08:00
parent d1b7c8b785
commit 6a5e68629e
2 changed files with 57 additions and 41 deletions

View File

@@ -352,14 +352,10 @@ namespace Modbus.Net
/// <returns>任务是否执行成功</returns> /// <returns>任务是否执行成功</returns>
public async Task<bool> InvokeOnce<TInterType>(TaskItem<TInterType> task) public async Task<bool> InvokeOnce<TInterType>(TaskItem<TInterType> task)
{ {
if (Machine.IsConnected) var ans = await task.Invoke(Machine, _tasks, task.Params?.Invoke(), task.TimeoutTime);
{
var ans = await task.Invoke(Machine, _tasks, task.Params, task.TimeoutTime);
task.Return?.Invoke(ans); task.Return?.Invoke(ans);
return true; return true;
} }
return false;
}
} }
internal class TaskMachineEqualityComparer<TKey> : IEqualityComparer<TaskMachine<TKey>> internal class TaskMachineEqualityComparer<TKey> : IEqualityComparer<TaskMachine<TKey>>
@@ -409,10 +405,8 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="returnFunc">返回值的处理函数</param> /// <param name="returnFunc">返回值的处理函数</param>
/// <param name="getDataType">返回值的键类型</param> /// <param name="getDataType">返回值的键类型</param>
/// <param name="getCycle">循环间隔(毫秒)</param>
/// <param name="sleepCycle">设备离线时的循环间隔(毫秒)</param>
/// <param name="timeout">任务的超时时间</param> /// <param name="timeout">任务的超时时间</param>
public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int getCycle, int sleepCycle, int timeout = 100000) public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int timeout = 100000)
{ {
Name = "GetDatas"; Name = "GetDatas";
TimeoutTime = timeout; TimeoutTime = timeout;
@@ -433,6 +427,19 @@ namespace Modbus.Net
}; };
Params = null; Params = null;
Return = returnFunc; Return = returnFunc;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="returnFunc">返回值的处理函数</param>
/// <param name="getDataType">返回值的键类型</param>
/// <param name="getCycle">循环间隔(毫秒)</param>
/// <param name="sleepCycle">设备离线时的循环间隔(毫秒)</param>
/// <param name="timeout">任务的超时时间</param>
public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int getCycle,
int sleepCycle, int timeout = 100000) : this(returnFunc, getDataType, timeout)
{
TimerDisconnectedTime = sleepCycle; TimerDisconnectedTime = sleepCycle;
TimerTime = getCycle; TimerTime = getCycle;
} }
@@ -450,24 +457,41 @@ namespace Modbus.Net
/// <param name="setDataType">写入值的键类型</param> /// <param name="setDataType">写入值的键类型</param>
/// <param name="returnFunc">返回值的处理函数</param> /// <param name="returnFunc">返回值的处理函数</param>
/// <param name="timeout">任务的超时时间</param> /// <param name="timeout">任务的超时时间</param>
public TaskItemSetData(Dictionary<string, double> values, MachineSetDataType setDataType, Action<bool> returnFunc = null, int timeout = 100000) public TaskItemSetData(Func<Dictionary<string, double>> values, MachineSetDataType setDataType, int timeout = 100000, Action<bool> returnFunc = null)
{ {
Name = "SetDatas"; Name = "SetDatas";
TimeoutTime = timeout; TimeoutTime = timeout;
Invoke = Invoke = async (machine, tasks, parameters, timeoutTime) => Invoke = async (machine, tasks, parameters, timeoutTime) =>
{ {
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(timeoutTime)); cts.CancelAfter(TimeSpan.FromMilliseconds(timeoutTime));
var ans = var ans =
await tasks.StartNew( await tasks.StartNew(
async () => await machine.InvokeMachineMethod<IMachineMethodData, async () => await machine.InvokeMachineMethod<IMachineMethodData,
Task<bool>>("SetDatasAsync", parameters[0], Task<bool>>("SetDatasAsync", setDataType, parameters[0]
setDataType).WithCancellation(cts.Token)).Unwrap(); ).WithCancellation(cts.Token)).Unwrap();
return ans; return ans;
}; };
Params = new object[] {values}; Params = () => new object[] {values()};
Return = returnFunc; Return = returnFunc;
} }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="values">写入的值</param>
/// <param name="setDataType">写入值的键类型</param>
/// <param name="returnFunc">返回值的处理函数</param>
/// <param name="getCycle">循环间隔(毫秒)</param>
/// <param name="sleepCycle">设备离线时的循环间隔(毫秒)</param>
/// <param name="timeout">任务的超时时间</param>
public TaskItemSetData(Func<Dictionary<string, double>> values, MachineSetDataType setDataType, int getCycle,
int sleepCycle, int timeout = 100000, Action<bool> returnFunc = null)
: this(values, setDataType, timeout, returnFunc)
{
TimerDisconnectedTime = sleepCycle;
TimerTime = getCycle;
}
} }
/// <summary> /// <summary>
@@ -514,7 +538,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 任务执行的参数 /// 任务执行的参数
/// </summary> /// </summary>
public object[] Params { get; set; } public Func<object[]> Params { get; set; }
/// <summary> /// <summary>
/// 返回值的处理函数 /// 返回值的处理函数
@@ -575,7 +599,7 @@ namespace Modbus.Net
Timer = new Timer(async state => Timer = new Timer(async state =>
{ {
if (!DetectConnected()) TimerChangeToDisconnect(); if (!DetectConnected()) TimerChangeToDisconnect();
var ans = await Invoke(GetMachine(), GetTaskFactory(), Params, TimeoutTime); var ans = await Invoke(GetMachine(), GetTaskFactory(), Params?.Invoke(), TimeoutTime);
Return?.Invoke(ans); Return?.Invoke(ans);
}, null, 0, TimerTime); }, null, 0, TimerTime);
} }

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Modbus.Net.Modbus; 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); _taskManager.AddMachine(machine);
var r = new Random(); var r = new Random();
_timer = new Timer(state => _timer = new Timer(async state =>
{ {
lock (_valueDic) lock (_valueDic)
{ {
@@ -111,42 +115,30 @@ namespace Modbus.Net.Tests
} }
}; };
} }
}, null, 0, 1000); await _taskManager.InvokeOnceAll(new TaskItemSetData(() => _valueDic, MachineSetDataType.CommunicationTag));
}, null, 0, 5000);
_taskManager.InvokeTimerAll(new TaskItemSetData(_valueDic, MachineSetDataType.CommunicationTag)
{
TimerTime = 2000,
TimeoutTime = 60000,
TimerDisconnectedTime = 10000
});
} }
[TestMethod] [TestMethod]
public void TaskManagerValueReadWriteTest() public async Task TaskManagerValueReadWriteTest()
{ {
var dicans = new Dictionary<string, double?>(); Thread.Sleep(2000);
_taskManager.InvokeTimerAll(new TaskItemGetData(
def =>
{
dicans = def.ReturnValues.ToDictionary(p => p.Key, p => p.Value.PlcValue);
}, MachineGetDataType.CommunicationTag, 2000, 10000, 60000));
var i = 5; var i = 5;
while (i > 0) while (i > 0)
{ {
Thread.Sleep(10000); Thread.Sleep(5000);
lock (dicans) await _taskManager.InvokeOnceAll(new TaskItemGetData(
{ def =>
lock (_valueDic)
{ {
var dicans = def.ReturnValues.ToDictionary(p => p.Key, p => p.Value.PlcValue);
Assert.AreEqual(dicans["A1"], _valueDic["A1"]); Assert.AreEqual(dicans["A1"], _valueDic["A1"]);
Assert.AreEqual(dicans["A2"], _valueDic["A2"]); Assert.AreEqual(dicans["A2"], _valueDic["A2"]);
Assert.AreEqual(dicans["A3"], _valueDic["A3"]); Assert.AreEqual(dicans["A3"], _valueDic["A3"]);
Assert.AreEqual(dicans["A4"], _valueDic["A4"]); Assert.AreEqual(dicans["A4"], _valueDic["A4"]);
Assert.AreEqual(dicans["A5"], _valueDic["A5"]); Assert.AreEqual(dicans["A5"], _valueDic["A5"]);
Assert.AreEqual(dicans["A6"], _valueDic["A6"]); Assert.AreEqual(dicans["A6"], _valueDic["A6"]);
} }, MachineGetDataType.CommunicationTag));
}
i--; i--;
} }
} }