diff --git a/Modbus.Net/ModBus.Net/BaseMachine.cs b/Modbus.Net/ModBus.Net/BaseMachine.cs index b321a8b..e2c146f 100644 --- a/Modbus.Net/ModBus.Net/BaseMachine.cs +++ b/Modbus.Net/ModBus.Net/BaseMachine.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace ModBus.Net { @@ -53,17 +54,22 @@ namespace ModBus.Net KeepConnect = keepConnect; } - public Dictionary GetDatas() + public Dictionary GetDatas() + { + return AsyncHelper.RunSync(GetDatasAsync); + } + + public async Task> GetDatasAsync() { Dictionary ans = new Dictionary(); if (!BaseUtility.IsConnected) { - BaseUtility.Connect(); + await BaseUtility.ConnectAsync(); } if (!BaseUtility.IsConnected) return null; foreach (var communicateAddress in CommunicateAddresses) { - var datas = BaseUtility.GetDatas(2, 0, AddressFormater.FormatAddress(communicateAddress.Area,communicateAddress.Address), communicateAddress.GetCount); + var datas = await BaseUtility.GetDatasAsync(2, 0, AddressFormater.FormatAddress(communicateAddress.Area,communicateAddress.Address), communicateAddress.GetCount); if (datas == null || datas.Length == 0) return null; int pos = 0; while (pos < communicateAddress.GetCount) @@ -94,6 +100,11 @@ namespace ModBus.Net return BaseUtility.Connect(); } + public async Task ConnectAsync() + { + return await BaseUtility.ConnectAsync(); + } + public bool Disconnect() { return BaseUtility.Disconnect(); diff --git a/Modbus.Net/ModBus.Net/BaseProtocal.cs b/Modbus.Net/ModBus.Net/BaseProtocal.cs index 6728642..ab85f4c 100644 --- a/Modbus.Net/ModBus.Net/BaseProtocal.cs +++ b/Modbus.Net/ModBus.Net/BaseProtocal.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Threading.Tasks; namespace ModBus.Net { @@ -62,6 +63,16 @@ namespace ModBus.Net return ProtocalLinker.SendReceive(ProtocalUnit.TranslateContent(content)); } + /// + /// 发送协议内容并接收,一般方法(异步) + /// + /// + /// + public virtual async Task SendReceiveAsync(params object[] content) + { + return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(content)); + } + /// /// 发送协议,通过传入需要使用的协议内容和输入结构 /// @@ -92,12 +103,48 @@ namespace ModBus.Net return null; } + /// + /// 发送协议,通过传入需要使用的协议内容和输入结构(异步) + /// + /// + /// + /// + public virtual async Task SendReceiveAsync(ProtocalUnit unit, InputStruct content) + { + int t = 0; + //如果为特别处理协议的话,跳过协议扩展收缩 + var formatContent = unit.Format(content); + if (formatContent != null) + { + byte[] receiveContent; + if (unit is SpecialProtocalUnit) + { + receiveContent = await ProtocalLinker.SendReceiveWithoutExtAndDecAsync(formatContent); + } + else + { + receiveContent = await ProtocalLinker.SendReceiveAsync(formatContent); + } + if (receiveContent != null) + { + return unit.Unformat(receiveContent, ref t); + } + } + return null; + } + /// /// 协议连接开始 /// /// public abstract bool Connect(); + /// + /// 协议连接开始(异步) + /// + /// + public abstract Task ConnectAsync(); + /// /// 协议连接断开 /// diff --git a/Modbus.Net/ModBus.Net/BaseUtility.cs b/Modbus.Net/ModBus.Net/BaseUtility.cs index 108ac5b..314125b 100644 --- a/Modbus.Net/ModBus.Net/BaseUtility.cs +++ b/Modbus.Net/ModBus.Net/BaseUtility.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; namespace ModBus.Net { @@ -36,6 +37,7 @@ namespace ModBus.Net /// /// 连接类型 public abstract void SetConnectionType(int connectionType); + /// /// 获取数据 /// @@ -44,7 +46,20 @@ namespace ModBus.Net /// 开始地址 /// 获取类型和个数 /// 接收到的byte数据 - protected abstract byte[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount); + protected virtual byte[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount) + { + return AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getByteCount)); + } + + /// + /// 获取数据(异步) + /// + /// 从站地址 + /// 主站地址 + /// 开始地址 + /// 获取类型和个数 + /// 接收到的byte数据 + protected abstract Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount); public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, KeyValuePair getTypeAndCount) @@ -63,6 +78,23 @@ namespace ModBus.Net } } + public virtual async Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, + KeyValuePair getTypeAndCount) + { + try + { + string typeName = getTypeAndCount.Key.FullName; + double bCount = ValueHelper.Instance.ByteLength[typeName]; + byte[] getBytes = await GetDatasAsync(belongAddress, masterAddress, startAddress, + (int) Math.Ceiling(bCount*getTypeAndCount.Value)); + return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); + } + catch (Exception) + { + return null; + } + } + public virtual T[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount) { @@ -78,6 +110,21 @@ namespace ModBus.Net } } + public virtual async Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, + int getByteCount) + { + try + { + var getBytes = await GetDatasAsync(belongAddress, masterAddress, startAddress, + new KeyValuePair(typeof(T), getByteCount)); + return ValueHelper.Instance.ObjectArrayToDestinationArray(getBytes); + } + catch (Exception) + { + return null; + } + } + public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, IEnumerable> getTypeAndCountList) { @@ -96,9 +143,30 @@ namespace ModBus.Net catch (Exception) { return null; - } - + } } + + public virtual async Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, + IEnumerable> getTypeAndCountList) + { + try + { + int bAllCount = 0; + foreach (var getTypeAndCount in getTypeAndCountList) + { + string typeName = getTypeAndCount.Key.FullName; + double bCount = ValueHelper.Instance.ByteLength[typeName]; + bAllCount += (int)Math.Ceiling(bCount * getTypeAndCount.Value); + } + byte[] getBytes = await GetDatasAsync(belongAddress, masterAddress, startAddress, bAllCount); + return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCountList); + } + catch (Exception) + { + return null; + } + } + /// /// 设置数据 /// @@ -107,8 +175,22 @@ namespace ModBus.Net /// 开始地址 /// 设置数据 /// 是否设置成功 - public abstract bool SetDatas(byte belongAddress, byte masterAddress, string startAddress, object[] setContents); + public virtual bool SetDatas(byte belongAddress, byte masterAddress, string startAddress, object[] setContents) + { + return AsyncHelper.RunSync(() => SetDatasAsync(belongAddress, masterAddress, startAddress, setContents)); + } + /// + /// 设置数据(异步) + /// + /// 从站地址 + /// 主站地址 + /// 开始地址 + /// 设置数据 + /// 是否设置成功 + public abstract Task SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents); + + /* /// /// 获取PLC时间 /// @@ -123,15 +205,22 @@ namespace ModBus.Net /// 设置PLC时间 /// 设置是否成功 public abstract bool SetTime(byte belongAddress, DateTime setTime); + */ public bool Connect() { return Wrapper.Connect(); } + public async Task ConnectAsync() + { + return await Wrapper.ConnectAsync(); + } + public bool Disconnect() { return Wrapper.Disconnect(); } + } } diff --git a/Modbus.Net/ModBus.Net/ModbusProtocal.cs b/Modbus.Net/ModBus.Net/ModbusProtocal.cs index c116185..49f6aff 100644 --- a/Modbus.Net/ModBus.Net/ModbusProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusProtocal.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; internal enum ModbusProtocalVariableFunctionCode : byte { @@ -44,6 +45,11 @@ namespace ModBus.Net { return ProtocalLinker.Connect(); } + + public override async Task ConnectAsync() + { + return await ProtocalLinker.ConnectAsync(); + } } #region 读PLC数据 diff --git a/Modbus.Net/ModBus.Net/ModbusUtility.cs b/Modbus.Net/ModBus.Net/ModbusUtility.cs index b407a84..10bfe4d 100644 --- a/Modbus.Net/ModBus.Net/ModbusUtility.cs +++ b/Modbus.Net/ModBus.Net/ModbusUtility.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; /// /// Modbus连接类型 @@ -65,28 +66,28 @@ namespace ModBus.Net ModbusType = (ModbusType) connectionType; } - protected override byte[] GetDatas(byte belongAddress, byte materAddress, string startAddress, int getByteCount) + protected override async Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount) { try { var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress, getByteCount % 2 == 0 ? (ushort)(getByteCount / 2) : (ushort)(getByteCount / 2 + 1), AddressTranslator); - var outputStruct = - Wrapper.SendReceive(Wrapper[typeof(ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct; + var outputStruct = await + Wrapper.SendReceiveAsync(Wrapper[typeof(ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct; return outputStruct.DataValue; } catch { return null; - } + } } - public override bool SetDatas(byte belongAddress, byte materAddress, string startAddress, object[] setContents) + public override async Task SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents) { try { var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents, AddressTranslator); - var outputStruct = - Wrapper.SendReceive(Wrapper[typeof(WriteDataModbusProtocal)], inputStruct) as + var outputStruct = await + Wrapper.SendReceiveAsync(Wrapper[typeof(WriteDataModbusProtocal)], inputStruct) as WriteDataModbusOutputStruct; if (outputStruct.WriteCount != setContents.Length) return false; return true; @@ -97,6 +98,7 @@ namespace ModBus.Net } } + /* public override DateTime GetTime(byte belongAddress) { try @@ -128,5 +130,6 @@ namespace ModBus.Net return false; } } + */ } } diff --git a/Modbus.Net/ModBus.Net/ProtocalLinker.cs b/Modbus.Net/ModBus.Net/ProtocalLinker.cs index 2eb0d0a..51cf9ff 100644 --- a/Modbus.Net/ModBus.Net/ProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ProtocalLinker.cs @@ -1,4 +1,5 @@ using System.Reflection; +using System.Threading.Tasks; namespace ModBus.Net { @@ -29,6 +30,11 @@ namespace ModBus.Net return _baseConnector.Connect(); } + public async Task ConnectAsync() + { + return await _baseConnector.ConnectAsync(); + } + public bool Disconnect() { return _baseConnector.Disconnect(); @@ -40,9 +46,19 @@ namespace ModBus.Net /// 发送协议的内容 /// 接收协议的内容 public virtual byte[] SendReceive(byte[] content) + { + return AsyncHelper.RunSync(() => SendReceiveAsync(content)); + } + + /// + /// 发送并接收数据 + /// + /// 发送协议的内容 + /// 接收协议的内容 + public virtual async Task SendReceiveAsync(byte[] content) { byte[] extBytes = BytesExtend(content); - byte[] receiveBytes = SendReceiveWithoutExtAndDec(extBytes); + byte[] receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes); return receiveBytes == null ? null : BytesDecact(receiveBytes); } @@ -52,9 +68,19 @@ namespace ModBus.Net /// 发送协议的内容 /// 接收协议的内容 public virtual byte[] SendReceiveWithoutExtAndDec(byte[] content) + { + return AsyncHelper.RunSync(() => SendReceiveWithoutExtAndDecAsync(content)); + } + + /// + /// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议 + /// + /// 发送协议的内容 + /// 接收协议的内容 + public virtual async Task SendReceiveWithoutExtAndDecAsync(byte[] content) { //发送数据 - byte[] receiveBytes = _baseConnector.SendMsg(content); + byte[] receiveBytes = await _baseConnector.SendMsgAsync(content); //容错处理 if (!CheckRight(receiveBytes)) return null; //返回字符 diff --git a/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs b/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs index 3a3da3c..893a05b 100644 --- a/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs +++ b/Modbus.Net/ModBus.Net/SimenseTcpProtocal.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; namespace ModBus.Net { @@ -31,45 +32,68 @@ namespace ModBus.Net } public override byte[] SendReceive(params object[] content) + { + return AsyncHelper.RunSync(() => SendReceiveAsync(content)); + } + + public override async Task SendReceiveAsync(params object[] content) { while (!ProtocalLinker.IsConnected) { - Connect(); + await ConnectAsync(); } - return base.SendReceive(content); + return await base.SendReceiveAsync(content); } public override OutputStruct SendReceive(ProtocalUnit unit, InputStruct content) + { + return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content)); + } + + public override async Task SendReceiveAsync(ProtocalUnit unit, InputStruct content) { if (!ProtocalLinker.IsConnected) { if (connectTryCount > 10) return null; - Connect(); + return await await ConnectAsync().ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null); } - return base.SendReceive(unit, content); + return await base.SendReceiveAsync(unit, content); } - private OutputStruct ForceSendReceive(ProtocalUnit unit, InputStruct content) + private async Task ForceSendReceiveAsync(ProtocalUnit unit, InputStruct content) { - return base.SendReceive(unit, content); + return await base.SendReceiveAsync(unit, content); } public override bool Connect() + { + return AsyncHelper.RunSync(ConnectAsync); + } + + public override async Task ConnectAsync() { connectTryCount++; ProtocalLinker = new SimenseTcpProtocalLinker(_ip); - if (ProtocalLinker.Connect()) + if (await ProtocalLinker.ConnectAsync()) { + connectTryCount = 0; var inputStruct = new CreateReferenceSimenseInputStruct(_tdpuSize, _taspSrc, _tsapDst); - var outputStruct = - (CreateReferenceSimenseOutputStruct) - ForceSendReceive(this[typeof (CreateReferenceSimenseProtocal)], inputStruct); - if (!ProtocalLinker.IsConnected) return false; - var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling, _maxCalled, _maxPdu); - var outputStruct2 = - (EstablishAssociationSimenseOutputStruct) - SendReceive(this[typeof (EstablishAssociationSimenseProtocal)], inputStruct2); - return true; + return + await await + ForceSendReceiveAsync(this[typeof (CreateReferenceSimenseProtocal)], inputStruct) + .ContinueWith(async answer => + { + if (!ProtocalLinker.IsConnected) return false; + var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling, + _maxCalled, + _maxPdu); + var outputStruct2 = + (EstablishAssociationSimenseOutputStruct) + await + SendReceiveAsync(this[typeof (EstablishAssociationSimenseProtocal)], + inputStruct2); + return true; + }); } return false; } diff --git a/Modbus.Net/ModBus.Net/SimenseUtility.cs b/Modbus.Net/ModBus.Net/SimenseUtility.cs index 6023886..223e1ab 100644 --- a/Modbus.Net/ModBus.Net/SimenseUtility.cs +++ b/Modbus.Net/ModBus.Net/SimenseUtility.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; public enum SimenseType { @@ -105,31 +106,30 @@ namespace ModBus.Net ConnectionType = (SimenseType) connectionType; } - protected override byte[] GetDatas(byte belongAddress, byte materAddress, string startAddress, int getByteCount) + protected override async Task GetDatasAsync(byte belongAddress, byte materAddress, string startAddress, int getByteCount) { try { var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xd3c7, SimenseTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator); var readRequestSimenseOutputStruct = - (ReadRequestSimenseOutputStruct) - Wrapper.SendReceive(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct); + (ReadRequestSimenseOutputStruct) await + Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct); return readRequestSimenseOutputStruct.GetValue; } catch (Exception) { return null; } - } - public override bool SetDatas(byte belongAddress, byte materAddress, string startAddress, object[] setContents) + public override async Task SetDatasAsync(byte belongAddress, byte materAddress, string startAddress, object[] setContents) { try { var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xd3c8, startAddress, setContents, AddressTranslator); var writeRequestSimenseOutputStruct = - (WriteRequestSimenseOutputStruct) - Wrapper.SendReceive(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct); + (WriteRequestSimenseOutputStruct) await + Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct); if (writeRequestSimenseOutputStruct.AccessResult == SimenseAccessResult.NoError) return true; else @@ -139,9 +139,9 @@ namespace ModBus.Net { return false; } - } + /* public override DateTime GetTime(byte belongAddress) { throw new NotImplementedException(); @@ -151,5 +151,6 @@ namespace ModBus.Net { throw new NotImplementedException(); } + */ } } diff --git a/Modbus.Net/ModBus.Net/TaskManager.cs b/Modbus.Net/ModBus.Net/TaskManager.cs index cc9993f..5403876 100644 --- a/Modbus.Net/ModBus.Net/TaskManager.cs +++ b/Modbus.Net/ModBus.Net/TaskManager.cs @@ -425,8 +425,8 @@ namespace ModBus.Net //var ans = machine.GetDatas(); CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(_getCycle)); - var ans = await _tasks.StartNew(machine.GetDatas, cts.Token); - //var ans = await Task.Factory.StartNew(machine.GetDatas, cts.Token); + var ans = await machine.GetDatasAsync().WithCancellation(cts.Token); + //var ans = await machine.GetDatasAsync().WithCancellation(cts.Token); if (!machine.IsConnected) { MoveMachineToUnlinked(machine.Id);