From 997ad00ce8b4e89a8681840c05184c85a03b5840 Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Thu, 2 Mar 2017 15:34:43 +0800 Subject: [PATCH] Fix --- Modbus.Net/Modbus.Net/BaseMachine.cs | 47 +++++++- Modbus.Net/Modbus.Net/TaskManager.cs | 163 ++++++++++++++++++++++++--- 2 files changed, 187 insertions(+), 23 deletions(-) diff --git a/Modbus.Net/Modbus.Net/BaseMachine.cs b/Modbus.Net/Modbus.Net/BaseMachine.cs index 2709fc4..4c13052 100644 --- a/Modbus.Net/Modbus.Net/BaseMachine.cs +++ b/Modbus.Net/Modbus.Net/BaseMachine.cs @@ -577,15 +577,16 @@ namespace Modbus.Net } } - public class BaseMachineEqualityComparer : IEqualityComparer> - where TKey : IEquatable where TUnitKey : IEquatable + public class BaseMachineEqualityComparer : IEqualityComparer> + where TKey : IEquatable { - public bool Equals(BaseMachine x, BaseMachine y) + public bool Equals(IMachineProperty x, IMachineProperty y) { - return x.ConnectionToken == y.ConnectionToken; + //1.3版本中需要修改这句话 + return x.Id.Equals(y.Id) || x.ConnectionToken == y.ConnectionToken; } - public int GetHashCode(BaseMachine obj) + public int GetHashCode(IMachineProperty obj) { return obj.GetHashCode(); } @@ -770,5 +771,41 @@ namespace Modbus.Net /// 标识设备的连接关键字 /// string ConnectionToken { get; } + + /// + /// 是否处于连接状态 + /// + bool IsConnected { get; } + + /// + /// 是否保持连接 + /// + bool KeepConnect { get; set; } + + /// + /// 读取数据 + /// + /// 从设备读取的数据 + Task> GetDatasAsync(MachineGetDataType getDataType); + + /// + /// 写入数据 + /// + /// 写入类型 + /// 需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述 + /// 是否写入成功 + Task SetDatasAsync(MachineSetDataType setDataType, Dictionary values); + + /// + /// 连接设备 + /// + /// 是否连接成功 + Task ConnectAsync(); + + /// + /// 断开设备 + /// + /// 是否断开成功 + bool Disconnect(); } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/TaskManager.cs b/Modbus.Net/Modbus.Net/TaskManager.cs index 5b39cb6..665a54b 100644 --- a/Modbus.Net/Modbus.Net/TaskManager.cs +++ b/Modbus.Net/Modbus.Net/TaskManager.cs @@ -22,6 +22,14 @@ namespace Modbus.Net Id } + /// + /// 返回结果的定义类 + /// + public class TaskReturnDef : TaskReturnDef + { + + } + /// /// 返回结果的定义类 /// @@ -201,22 +209,89 @@ namespace Modbus.Net /// /// 任务调度器 /// - public class TaskManager : TaskManager + public class TaskManager : TaskManager { public TaskManager(int maxRunningTask, int getCycle, bool keepConnect, MachineDataType dataType = MachineDataType.CommunicationTag) : base(maxRunningTask, getCycle, keepConnect, dataType) { } + + public new delegate void ReturnValuesDelegate(TaskReturnDef returnValue); + + public new event ReturnValuesDelegate ReturnValues; + + /// + /// 执行对具体设备的数据更新 + /// + /// 设备的实例 + /// + protected new async Task RunTask(IMachineProperty machine) + { + try + { + //调试代码,调试时取消下面一下代码的注释,会同步调用获取数据。 + //var ans = machine.GetDatas(); + //设置Cancellation Token + var cts = new CancellationTokenSource(); + //超时后取消任务 + cts.CancelAfter(TimeSpan.FromSeconds(GetCycle)); + //读取数据 + var ans = await machine.GetDatasAsync(GetDataType).WithCancellation(cts.Token); + if (!machine.IsConnected) + { + MoveMachineToUnlinked(machine.Id); + } + else + { + MoveMachineToLinked(machine.Id); + } + ReturnValues?.Invoke(new TaskReturnDef + { + MachineId = machine.Id, + ReturnValues = ans + }); + } + catch (Exception e) + { + if (!machine.IsConnected) + { + MoveMachineToUnlinked(machine.Id); + } + ReturnValues?.Invoke(new TaskReturnDef + { + MachineId = machine.Id, + ReturnValues = null + }); + } + } + + public void AddMachine(BaseMachine machine) + { + base.AddMachine(machine); + } + + public void AddMachines(IEnumerable machines) + { + base.AddMachines(machines); + } + + public BaseMachine GetMachineById(string id) + { + return base.GetMachineById(id) as BaseMachine; + } + + public BaseMachine GetMachineByConnectionToken(string connectionToken) + { + return base.GetMachineByConnectionToken(connectionToken) as BaseMachine; + } } /// /// 任务调度器 /// /// - /// - public class TaskManager where TMachineKey : IEquatable - where TUnitKey : IEquatable + public class TaskManager where TMachineKey : IEquatable { /// /// 返回数据代理 @@ -227,12 +302,12 @@ namespace Modbus.Net /// /// 正在运行的设备 /// - private readonly HashSet> _machines; + private readonly HashSet> _machines; /// /// 不在运行的设备 /// - private readonly HashSet> _unlinkedMachines; + private readonly HashSet> _unlinkedMachines; private CancellationTokenSource _cts; @@ -278,9 +353,9 @@ namespace Modbus.Net { _scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask); _machines = - new HashSet>(new BaseMachineEqualityComparer()); + new HashSet>(new BaseMachineEqualityComparer()); _unlinkedMachines = - new HashSet>(new BaseMachineEqualityComparer()); + new HashSet>(new BaseMachineEqualityComparer()); _getCycle = getCycle; KeepConnect = keepConnect; MachineDataType = dataType; @@ -411,7 +486,7 @@ namespace Modbus.Net /// 添加一台设备 /// /// 设备 - public void AddMachine(BaseMachine machine) + public void AddMachine(BaseMachine machine) where TUnitKey : IEquatable { machine.KeepConnect = KeepConnect; lock (_machines) @@ -424,7 +499,7 @@ namespace Modbus.Net /// 添加多台设备 /// /// 设备的列表 - public void AddMachines(IEnumerable> machines) + public void AddMachines(IEnumerable> machines) where TUnitKey : IEquatable { lock (_machines) { @@ -435,6 +510,58 @@ namespace Modbus.Net } } + public BaseMachine GetMachineById(TMachineKey id) + where TUnitKey : IEquatable + { + try + { + IMachineProperty machine; + lock (_machines) + { + machine = _machines.FirstOrDefault(p => p.Id.Equals(id)); + if (machine == null) + { + lock (_unlinkedMachines) + { + machine = _unlinkedMachines.FirstOrDefault(p => p.Id.Equals(id)); + } + } + } + return machine as BaseMachine; + } + catch (Exception e) + { + Console.WriteLine($"设备返回错误 {e.Message}"); + return null; + } + } + + public BaseMachine GetMachineByConnectionToken(string connectionToken) + where TUnitKey : IEquatable + { + try + { + IMachineProperty machine; + lock (_machines) + { + machine = _machines.FirstOrDefault(p => p.ConnectionToken == connectionToken); + if (machine == null) + { + lock (_unlinkedMachines) + { + machine = _unlinkedMachines.FirstOrDefault(p => p.ConnectionToken == connectionToken); + } + } + } + return machine as BaseMachine; + } + catch (Exception e) + { + Console.WriteLine($"设备返回错误 {e.Message}"); + return null; + } + } + /// /// 根据设备的连接地址移除设备 /// @@ -473,7 +600,7 @@ namespace Modbus.Net /// 设备的id public void MoveMachineToUnlinked(TMachineKey id) { - IEnumerable> machines; + IEnumerable> machines; lock (_machines) { machines = _machines.Where(c => c.Id.Equals(id)).ToList(); @@ -495,7 +622,7 @@ namespace Modbus.Net /// 设备的id public void MoveMachineToLinked(TMachineKey id) { - IEnumerable> machines; + IEnumerable> machines; lock (_unlinkedMachines) { machines = _unlinkedMachines.Where(c => c.Id.Equals(id)).ToList(); @@ -515,7 +642,7 @@ namespace Modbus.Net /// 移除设备 /// /// 设备的实例 - public void RemoveMachine(BaseMachine machine) + public void RemoveMachine(IMachineProperty machine) { lock (_machines) { @@ -554,8 +681,8 @@ namespace Modbus.Net try { var tasks = new List(); - var saveMachines = new HashSet>(); - IEnumerable> saveMachinesEnum; + var saveMachines = new HashSet>(); + IEnumerable> saveMachinesEnum; lock (_machines) { saveMachines.UnionWith(_machines); @@ -585,7 +712,7 @@ namespace Modbus.Net try { var tasks = new List(); - var saveMachines = new HashSet>(); + var saveMachines = new HashSet>(); lock (_unlinkedMachines) { saveMachines.UnionWith(_unlinkedMachines); @@ -614,7 +741,7 @@ namespace Modbus.Net public async Task SetDatasAsync(string connectionToken, Dictionary values) { - BaseMachine machine = null; + IMachineProperty machine = null; lock (_machines) { machine = _machines.FirstOrDefault(p => p.ConnectionToken == connectionToken); @@ -659,7 +786,7 @@ namespace Modbus.Net /// /// 设备的实例 /// - private async Task RunTask(BaseMachine machine) + protected async Task RunTask(IMachineProperty machine) { try {