From 1461efa42f46d5948f76fbc7ffc6bae2c95b1af4 Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Mon, 15 May 2017 15:26:00 +0800 Subject: [PATCH] 2017-05-15 update 2 Add comments. --- .../Modbus.Net.Modbus.csproj | 4 + .../Modbus.Net.OPC/Modbus.Net.OPC.csproj | 1 + .../Modbus.Net.Siemens.csproj | 4 + Modbus.Net/Modbus.Net/ComConnector.cs | 2 +- Modbus.Net/src/Base.Common/AsyncHelper.cs | 7 + Modbus.Net/src/Base.Common/BaseMachine.cs | 16 + Modbus.Net/src/Base.Common/CRC16.cs | 7 +- Modbus.Net/src/Base.Common/TaskManager.cs | 349 ++++++++++++++++-- Modbus.Net/src/Base.Common/TypeExtensions.cs | 6 + Modbus.Net/src/Base.Common/ValueHelper.cs | 3 +- 10 files changed, 362 insertions(+), 37 deletions(-) diff --git a/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj b/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj index d0c29f2..fef1838 100644 --- a/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj +++ b/Modbus.Net/Modbus.Net.Modbus/Modbus.Net.Modbus.csproj @@ -23,6 +23,10 @@ bin\Debug\net45\Modbus.Net.Modbus.xml + + + + diff --git a/Modbus.Net/Modbus.Net.OPC/Modbus.Net.OPC.csproj b/Modbus.Net/Modbus.Net.OPC/Modbus.Net.OPC.csproj index 3f38142..34e799c 100644 --- a/Modbus.Net/Modbus.Net.OPC/Modbus.Net.OPC.csproj +++ b/Modbus.Net/Modbus.Net.OPC/Modbus.Net.OPC.csproj @@ -25,6 +25,7 @@ + diff --git a/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj b/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj index 3c27504..b863ece 100644 --- a/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj +++ b/Modbus.Net/Modbus.Net.Siemens/Modbus.Net.Siemens.csproj @@ -22,6 +22,10 @@ bin\Debug\net45\Modbus.Net.Siemens.xml + + + + diff --git a/Modbus.Net/Modbus.Net/ComConnector.cs b/Modbus.Net/Modbus.Net/ComConnector.cs index e5b29fd..f0efd88 100644 --- a/Modbus.Net/Modbus.Net/ComConnector.cs +++ b/Modbus.Net/Modbus.Net/ComConnector.cs @@ -409,7 +409,7 @@ namespace Modbus.Net Array.Copy(data, 0, returndata, 0, i); return returndata; } - catch (Exception ex) + catch (Exception) { Dispose(); return null; diff --git a/Modbus.Net/src/Base.Common/AsyncHelper.cs b/Modbus.Net/src/Base.Common/AsyncHelper.cs index 456c170..842fd28 100644 --- a/Modbus.Net/src/Base.Common/AsyncHelper.cs +++ b/Modbus.Net/src/Base.Common/AsyncHelper.cs @@ -55,6 +55,13 @@ namespace Modbus.Net return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } + /// + /// Add a CancellationToken to async task + /// + /// type of a task + /// Task + /// Cancellation token + /// Task with cancellation token public static Task WithCancellation(this Task task, CancellationToken token) { diff --git a/Modbus.Net/src/Base.Common/BaseMachine.cs b/Modbus.Net/src/Base.Common/BaseMachine.cs index 757df30..6f8bf21 100644 --- a/Modbus.Net/src/Base.Common/BaseMachine.cs +++ b/Modbus.Net/src/Base.Common/BaseMachine.cs @@ -662,6 +662,10 @@ namespace Modbus.Net return BaseUtility.Disconnect(); } + /// + /// 获取设备的Id,字符串格式 + /// + /// public string GetMachineIdString() { return Id.ToString(); @@ -821,12 +825,20 @@ namespace Modbus.Net /// public UnitExtend UnitExtend { get; set; } + /// + /// 两个地址是否一致 + /// + /// 另一个地址 + /// 是否一致 public bool Equals(AddressUnit other) { return (Area.ToUpper() == other.Area.ToUpper() && Address == other.Address) || Id.Equals(other.Id); } } + /// + /// 没有Id的设备属性 + /// public interface IMachinePropertyWithoutKey { /// @@ -888,6 +900,10 @@ namespace Modbus.Net /// 是否断开成功 bool Disconnect(); + /// + /// 获取设备的Id的字符串 + /// + /// string GetMachineIdString(); } diff --git a/Modbus.Net/src/Base.Common/CRC16.cs b/Modbus.Net/src/Base.Common/CRC16.cs index 67594dc..5303dba 100644 --- a/Modbus.Net/src/Base.Common/CRC16.cs +++ b/Modbus.Net/src/Base.Common/CRC16.cs @@ -44,7 +44,6 @@ namespace Modbus.Net /// /// 发送或返回的命令,CRC码除外 /// 存储CRC码的字节的数组 - /// 生成的CRC码 public short GetCRC(byte[] message, ref byte[] Rcvbuf) { int IX, IY, CRC; @@ -83,7 +82,7 @@ namespace Modbus.Net /// /// CRC校验 /// - /// ST开头,&&结尾 + /// 需要校验的字节数组 /// 十六进制数 public bool CrcEfficacy(byte[] byteframe) { @@ -149,15 +148,13 @@ namespace Modbus.Net decByteTotal = 255 - decByteTotal + 1; decByteTotal = decByteTotal & 255; - int a, b = 0; - string hexByte = "", hexTotal = ""; double i; for (i = 0; decByteTotal > 0; i++) { //b = Convert.ToInt32(System.Math.Pow(16.0, i)); - a = decByteTotal%16; + var a = decByteTotal%16; decByteTotal /= 16; if (a <= 9) hexByte = a.ToString(); diff --git a/Modbus.Net/src/Base.Common/TaskManager.cs b/Modbus.Net/src/Base.Common/TaskManager.cs index 00ae740..e73aa17 100644 --- a/Modbus.Net/src/Base.Common/TaskManager.cs +++ b/Modbus.Net/src/Base.Common/TaskManager.cs @@ -25,10 +25,19 @@ namespace Modbus.Net /// public class DataReturnDef where TMachineKey : IEquatable { + /// + /// 设备的Id + /// public TMachineKey MachineId { get; set; } + /// + /// 返回的数据值 + /// public Dictionary ReturnValues { get; set; } } + /// + /// Limited concurrency level task scheduler + /// public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { /// @@ -192,20 +201,45 @@ namespace Modbus.Net } } + /// + /// 具有任务管理的设备 + /// + /// 设备的Id类型 public class TaskMachine where TMachineKey : IEquatable { - private TaskFactory _tasks { get; } + /// + /// 任务工厂 + /// + private readonly TaskFactory _tasks; + /// + /// 构造函数 + /// + /// 设备 + /// 任务工厂 public TaskMachine(IMachineProperty machine, TaskFactory taskFactory) { Machine = machine; _tasks = taskFactory; + TasksWithTimer = new List(); } + /// + /// 设备 + /// public IMachineProperty Machine { get; } - public List TasksWithTimer { get; set; } + /// + /// 任务调度器 + /// + public List TasksWithTimer { get; } + /// + /// 定时方式启动任务 + /// + /// 任务返回值的类型 + /// 任务 + /// 任务是否执行成功 public bool InvokeTimer(TaskItem task) { task.DetectConnected = () => Machine.IsConnected; @@ -221,6 +255,11 @@ namespace Modbus.Net return false; } + /// + /// 停止任务 + /// + /// 任务的名称 + /// 是否停止成功 public bool StopTimer(string taskItemName) { if (TasksWithTimer.Exists(taskCon => taskCon.Name == taskItemName)) @@ -233,6 +272,10 @@ namespace Modbus.Net return false; } + /// + /// 停止所有任务 + /// + /// 是否停止成功 public bool StopAllTimers() { bool ans = true; @@ -243,6 +286,11 @@ namespace Modbus.Net return ans; } + /// + /// 暂时任务 + /// + /// 任务的名称 + /// 是否暂停成功 public bool PauseTimer(string taskItemName) { if (TasksWithTimer.Exists(taskCon => taskCon.Name == taskItemName)) @@ -254,6 +302,10 @@ namespace Modbus.Net return false; } + /// + /// 暂停所有任务 + /// + /// 是否暂停成功 public bool PauseAllTimers() { bool ans = true; @@ -264,6 +316,11 @@ namespace Modbus.Net return ans; } + /// + /// 恢复任务 + /// + /// 任务的名称 + /// 是否恢复任务 public bool ContinueTimer(string taskItemName) { if (TasksWithTimer.Exists(taskCon => taskCon.Name == taskItemName)) @@ -275,6 +332,10 @@ namespace Modbus.Net return false; } + /// + /// 恢复所有任务 + /// + /// 是否恢复成功 public bool ContinueAllTimers() { bool ans = true; @@ -285,12 +346,18 @@ namespace Modbus.Net return ans; } + /// + /// 执行任务一次 + /// + /// 任务返回值的类型 + /// 任务 + /// 任务是否执行成功 public async Task InvokeOnce(TaskItem task) { if (Machine.IsConnected) { var ans = await task.Invoke(Machine, _tasks, task.Params); - task.Return(ans); + task.Return?.Invoke(ans); return true; } return false; @@ -311,17 +378,40 @@ namespace Modbus.Net } } + /// + /// 任务的接口 + /// public interface ITaskItem { + /// + /// 任务的名称 + /// string Name { get; set; } + /// + /// 启动计时器 + /// + /// bool StartTimer(); + /// + /// 停止计时器 + /// + /// bool StopTimer(); } + /// + /// 获取数据的预定义任务 + /// public class TaskItemGetData : TaskItem { + /// + /// 构造函数 + /// + /// 返回值的处理函数 + /// 循环间隔(毫秒) + /// 设备离线时的循环间隔(毫秒) public TaskItemGetData(Action returnFunc, int getCycle, int sleepCycle) { Name = "GetDatas"; @@ -346,10 +436,18 @@ namespace Modbus.Net TimerTime = getCycle; } } - + + /// + /// 写入数据的预定义任务 + /// public class TaskItemSetData : TaskItem { - public TaskItemSetData(Dictionary values) + /// + /// 构造函数 + /// + /// 写入的值 + /// 返回值的处理函数 + public TaskItemSetData(Dictionary values, Action returnFunc = null) { Name = "SetDatas"; Invoke = Invoke = async (machine, tasks, parameters) => @@ -364,50 +462,106 @@ namespace Modbus.Net return ans; }; Params = new object[]{values}; + Return = returnFunc; } } + /// + /// 任务 + /// + /// 任务返回值的类型 public class TaskItem : ITaskItem, IEquatable> { + /// + /// 名称 + /// public string Name { get; set; } + /// + /// 定时器 + /// private Timer Timer { get; set; } + /// + /// 定时器的时间 + /// public int TimerTime { get; set; } + /// + /// 离线定时器 + /// private Timer TimerDisconnected { get; set; } + /// + /// 离线定时器的时间 + /// public int TimerDisconnectedTime { get; set; } + /// + /// 执行的任务 + /// public Func> Invoke { get; set; } + /// + /// 检测设备的在线状态 + /// internal Func DetectConnected { get; set; } + /// + /// 任务执行的参数 + /// public object[] Params { get; set; } + /// + /// 返回值的处理函数 + /// public Action Return { get; set; } + /// + /// 获取设备 + /// internal Func GetMachine { get; set; } + /// + /// 获取任务工厂 + /// internal Func GetTaskFactory { get; set; } + /// + /// 是否相等 + /// + /// 另一个实例 + /// 是否相等 public bool Equals(TaskItem other) { return Name == other?.Name; } + /// + /// 启动定时器 + /// + /// 是否成功 public bool StartTimer() { ActivateTimerDisconnected(); return true; } + /// + /// 激活定时器 + /// private void ActivateTimer() { Timer = new Timer(async state => { if (!DetectConnected()) TimerChangeToDisconnect(); var ans = await Invoke(GetMachine(),GetTaskFactory(),Params); - Return(ans); + Return?.Invoke(ans); }, null, 0, TimerTime); } + /// + /// 反激活定时器 + /// private void DeactivateTimer() { Timer.Dispose(); Timer = null; } + /// + /// 激活离线定时器 + /// private void ActivateTimerDisconnected() { TimerDisconnected = new Timer(async state => @@ -417,12 +571,19 @@ namespace Modbus.Net }, null, 0, TimerDisconnectedTime); } + /// + /// 反激活离线定时器 + /// private void DeactivateTimerDisconnected() { TimerDisconnected.Dispose(); TimerDisconnected = null; } + /// + /// 将定时器切换至在线 + /// + /// private bool TimerChangeToConnect() { DeactivateTimerDisconnected(); @@ -430,6 +591,10 @@ namespace Modbus.Net return true; } + /// + /// 将定时器切换至离线 + /// + /// private bool TimerChangeToDisconnect() { DeactivateTimer(); @@ -437,6 +602,10 @@ namespace Modbus.Net return true; } + /// + /// 停止定时器 + /// + /// public bool StopTimer() { DeactivateTimer(); @@ -450,27 +619,51 @@ namespace Modbus.Net /// public class TaskManager : TaskManager { + /// + /// 构造一个TaskManager + /// + /// 同时可以运行的任务数 + /// 读取数据后是否保持连接 + /// 获取与设置数据的方式 public TaskManager(int maxRunningTask, bool keepConnect, MachineDataType dataType = MachineDataType.CommunicationTag) : base(maxRunningTask, keepConnect, dataType) { } + /// + /// 添加一台设备 + /// + /// 设备 public void AddMachine(BaseMachine machine) { base.AddMachine(machine); } + /// + /// 添加多台设备 + /// + /// 多台设备 public void AddMachines(IEnumerable machines) { base.AddMachines(machines); } + /// + /// 通过Id获取设备 + /// + /// 设备Id + /// 获取的设备 public BaseMachine GetMachineById(string id) { return base.GetMachineById(id) as BaseMachine; } + /// + /// 通过通讯标志获取设备 + /// + /// 通讯标志 + /// 获取的设备 public BaseMachine GetMachineByConnectionToken(string connectionToken) { return base.GetMachineByConnectionToken(connectionToken) as BaseMachine; @@ -480,7 +673,7 @@ namespace Modbus.Net /// /// 任务调度器 /// - /// + /// 设备Id的类型 public class TaskManager where TMachineKey : IEquatable { /// @@ -488,6 +681,9 @@ namespace Modbus.Net /// private readonly HashSet> _machines; + /// + /// 全局任务取消标志 + /// private CancellationTokenSource _cts; /// @@ -554,6 +750,9 @@ namespace Modbus.Net } } + /// + /// 设备读写设备的关键字 + /// public MachineDataType MachineDataType { set @@ -588,7 +787,13 @@ namespace Modbus.Net } } + /// + /// 设备读数据的关键字 + /// public MachineGetDataType GetDataType { get; set; } + /// + /// 设备写数据的关键字 + /// public MachineSetDataType SetDataType { get; set; } /// @@ -615,7 +820,7 @@ namespace Modbus.Net machine.KeepConnect = KeepConnect; lock (_machines) { - _machines.Add(new TaskMachine(machine, _tasks) {TasksWithTimer = new List()}); + _machines.Add(new TaskMachine(machine, _tasks)); } } @@ -635,6 +840,12 @@ namespace Modbus.Net } } + /// + /// 通过Id获取设备 + /// + /// 设备地址Id的类型 + /// 设备的Id + /// 获取设备 public BaseMachine GetMachineById(TMachineKey id) where TUnitKey : IEquatable { @@ -654,6 +865,12 @@ namespace Modbus.Net } } + /// + /// 通过通讯标志获取设备 + /// + /// 设备地址Id的类型 + /// 通讯标志 + /// 获取的数据 public BaseMachine GetMachineByConnectionToken(string connectionToken) where TUnitKey : IEquatable { @@ -709,78 +926,117 @@ namespace Modbus.Net } } + /// + /// 所有设备执行定时任务 + /// + /// 任务返回值的类型 + /// 任务 + /// 所有任务是否执行成功 public bool InvokeTimerAll(TaskItem item) { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.InvokeTimer(item); + ans &= machine.InvokeTimer(item); } } - return true; + return ans; } + /// + /// 所有设备停止执行所有任务 + /// + /// 所有任务是否停止成功 public bool StopTimerAll() { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.StopAllTimers(); + ans &= machine.StopAllTimers(); } } - return true; + return ans; } + /// + /// 所有设备停止执行某一个任务 + /// + /// 任务名称 + /// 任务是否停止成功 public bool StopTimerAll(string taskItemName) { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.StopTimer(taskItemName); + ans &= machine.StopTimer(taskItemName); } } - return true; + return ans; } + /// + /// 所有设备暂停执行所有任务 + /// + /// 任务是否暂停成功 public bool PauseTimerAll() { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.PauseAllTimers(); + ans &= machine.PauseAllTimers(); } } - return true; + return ans; } + /// + /// 所有设备暂停执行某一个任务 + /// + /// 任务的名称 + /// 任务是否暂停成功 public bool PauseTimerAll(string taskItemName) { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.PauseTimer(taskItemName); + ans &= machine.PauseTimer(taskItemName); } } - return true; + return ans; } + /// + /// 所有设备继续执行所有任务 + /// + /// 所有任务是否继续执行成功 public bool ContinueTimerAll() { + var ans = true; lock (_machines) { foreach (var machine in _machines) { - machine.ContinueAllTimers(); + ans &= machine.ContinueAllTimers(); } } - return true; + return ans; } + /// + /// 所有设备继续执行某一个任务 + /// + /// 任务的名称 + /// 任务是否继续执行成功 public bool ConinueTimerAll(string taskItemName) { lock (_machines) @@ -793,6 +1049,12 @@ namespace Modbus.Net return true; } + /// + /// 所有设备执行一个一次性任务 + /// + /// 任务的返回值类型 + /// 任务 + /// 任务是否执行成功 public async Task InvokeOnceAll(TaskItem item) { var tasks = new List>(); @@ -807,57 +1069,84 @@ namespace Modbus.Net return ans.All(p=>p); } + /// + /// 某个设备执行一个一次性任务 + /// + /// 任务的返回值类型 + /// 设备的Id + /// 任务 + /// 任务是否执行成功 public async Task InvokeOnceForMachine(TMachineKey machineId, TaskItem item) { var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId)); if (machine != null) { - await machine.InvokeOnce(item); - return true; + return await machine.InvokeOnce(item); } return false; } + /// + /// 某个设备执行一个定时任务 + /// + /// 任务的返回值类型 + /// 设备的Id + /// 任务 + /// 任务是否执行成功 public bool InvokeTimerForMachine(TMachineKey machineId, TaskItem item) { var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId)); if (machine != null) { - machine.InvokeTimer(item); - return true; + return machine.InvokeTimer(item); } return false; } + /// + /// 某个设备停止一个定时任务 + /// + /// 任务的Id + /// 任务的名称 + /// 任务是否停止成功 public bool StopTimerForMachine(TMachineKey machineId, string taskItemName) { var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId)); if (machine != null) { - machine.StopTimer(taskItemName); - return true; + return machine.StopTimer(taskItemName); } return false; } + /// + /// 某个设备暂停一个定时任务 + /// + /// 任务的Id + /// 任务的名称 + /// 任务是否暂停成功 public bool PauseTimerForMachine(TMachineKey machineId, string taskItemName) { var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId)); if (machine != null) { - machine.PauseTimer(taskItemName); - return true; + return machine.PauseTimer(taskItemName); } return false; } + /// + /// 某个设备继续进行一个定时任务 + /// + /// 任务的Id + /// 任务的名称 + /// 任务是否继续运行成功 public bool ContinueTimerForMachine(TMachineKey machineId, string taskItemName) { var machine = _machines.FirstOrDefault(p => p.Machine.Id.Equals(machineId)); if (machine != null) { - machine.ContinueTimer(taskItemName); - return true; + return machine.ContinueTimer(taskItemName); } return false; } diff --git a/Modbus.Net/src/Base.Common/TypeExtensions.cs b/Modbus.Net/src/Base.Common/TypeExtensions.cs index 282f839..fb8778d 100644 --- a/Modbus.Net/src/Base.Common/TypeExtensions.cs +++ b/Modbus.Net/src/Base.Common/TypeExtensions.cs @@ -8,6 +8,9 @@ using System.Threading.Tasks; namespace Modbus.Net { + /// + /// Extensions of Reflection + /// public static class TypeExtensions { #region Public Methods @@ -22,6 +25,9 @@ namespace Modbus.Net /// /// The types of the method's arguments to match. /// + /// + /// Is method Generic Method. + /// /// /// /// Thrown if: diff --git a/Modbus.Net/src/Base.Common/ValueHelper.cs b/Modbus.Net/src/Base.Common/ValueHelper.cs index c5c953e..01b34b3 100644 --- a/Modbus.Net/src/Base.Common/ValueHelper.cs +++ b/Modbus.Net/src/Base.Common/ValueHelper.cs @@ -1244,7 +1244,8 @@ namespace Modbus.Net /// 设置对应数字中相应位置的bit的值 /// /// byte数子 - /// 设置位置 + /// 设置的位置 + /// 设置的子位置 /// 设置bit大小,true为1,false为0 /// 设置是否成功 public override bool SetBit(byte[] number, int pos, int subPos, bool setBit)