2015-09-17 update 1 change all connections to async connection

This commit is contained in:
parallelbgls@outlook.com
2015-09-17 17:12:33 +08:00
parent 6f99bc5ce4
commit f9a8a57f0e
9 changed files with 249 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ModBus.Net
{
@@ -54,16 +55,21 @@ namespace ModBus.Net
}
public Dictionary<string, ReturnUnit> GetDatas()
{
return AsyncHelper.RunSync(GetDatasAsync);
}
public async Task<Dictionary<string,ReturnUnit>> GetDatasAsync()
{
Dictionary<string, ReturnUnit> ans = new Dictionary<string, ReturnUnit>();
if (!BaseUtility.IsConnected)
{
BaseUtility.Connect();
await BaseUtility.ConnectAsync();
}
if (!BaseUtility.IsConnected) return null;
foreach (var communicateAddress in CommunicateAddresses)
{
var datas = BaseUtility.GetDatas<byte>(2, 0, AddressFormater.FormatAddress(communicateAddress.Area,communicateAddress.Address), communicateAddress.GetCount);
var datas = await BaseUtility.GetDatasAsync<byte>(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<bool> ConnectAsync()
{
return await BaseUtility.ConnectAsync();
}
public bool Disconnect()
{
return BaseUtility.Disconnect();

View File

@@ -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));
}
/// <summary>
/// 发送协议内容并接收,一般方法(异步)
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public virtual async Task<byte[]> SendReceiveAsync(params object[] content)
{
return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(content));
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary>
@@ -92,12 +103,48 @@ namespace ModBus.Net
return null;
}
/// <summary>
/// 发送协议,通过传入需要使用的协议内容和输入结构(异步)
/// </summary>
/// <param name="unit"></param>
/// <param name="content"></param>
/// <returns></returns>
public virtual async Task<OutputStruct> 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;
}
/// <summary>
/// 协议连接开始
/// </summary>
/// <returns></returns>
public abstract bool Connect();
/// <summary>
/// 协议连接开始(异步)
/// </summary>
/// <returns></returns>
public abstract Task<bool> ConnectAsync();
/// <summary>
/// 协议连接断开
/// </summary>

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ModBus.Net
{
@@ -36,6 +37,7 @@ namespace ModBus.Net
/// </summary>
/// <param name="connectionType">连接类型</param>
public abstract void SetConnectionType(int connectionType);
/// <summary>
/// 获取数据
/// </summary>
@@ -44,7 +46,20 @@ namespace ModBus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取类型和个数</param>
/// <returns>接收到的byte数据</returns>
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));
}
/// <summary>
/// 获取数据(异步)
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取类型和个数</param>
/// <returns>接收到的byte数据</returns>
protected abstract Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount);
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
KeyValuePair<Type, int> getTypeAndCount)
@@ -63,6 +78,23 @@ namespace ModBus.Net
}
}
public virtual async Task<object[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress,
KeyValuePair<Type, int> 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<T>(byte belongAddress, byte masterAddress, string startAddress,
int getByteCount)
{
@@ -78,6 +110,21 @@ namespace ModBus.Net
}
}
public virtual async Task<T[]> GetDatasAsync<T>(byte belongAddress, byte masterAddress, string startAddress,
int getByteCount)
{
try
{
var getBytes = await GetDatasAsync(belongAddress, masterAddress, startAddress,
new KeyValuePair<Type, int>(typeof(T), getByteCount));
return ValueHelper.Instance.ObjectArrayToDestinationArray<T>(getBytes);
}
catch (Exception)
{
return null;
}
}
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
{
@@ -97,8 +144,29 @@ namespace ModBus.Net
{
return null;
}
}
public virtual async Task<object[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress,
IEnumerable<KeyValuePair<Type, int>> 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;
}
}
/// <summary>
/// 设置数据
/// </summary>
@@ -107,8 +175,22 @@ namespace ModBus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">设置数据</param>
/// <returns>是否设置成功</returns>
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));
}
/// <summary>
/// 设置数据(异步)
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">设置数据</param>
/// <returns>是否设置成功</returns>
public abstract Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents);
/*
/// <summary>
/// 获取PLC时间
/// </summary>
@@ -123,15 +205,22 @@ namespace ModBus.Net
/// <param name="setTime">设置PLC时间</param>
/// <returns>设置是否成功</returns>
public abstract bool SetTime(byte belongAddress, DateTime setTime);
*/
public bool Connect()
{
return Wrapper.Connect();
}
public async Task<bool> ConnectAsync()
{
return await Wrapper.ConnectAsync();
}
public bool Disconnect()
{
return Wrapper.Disconnect();
}
}
}

View File

@@ -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<bool> ConnectAsync()
{
return await ProtocalLinker.ConnectAsync();
}
}
#region PLC数据

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
/// <summary>
/// Modbus连接类型
@@ -65,13 +66,13 @@ namespace ModBus.Net
ModbusType = (ModbusType) connectionType;
}
protected override byte[] GetDatas(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
protected override async Task<byte[]> 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
@@ -80,13 +81,13 @@ namespace ModBus.Net
}
}
public override bool SetDatas(byte belongAddress, byte materAddress, string startAddress, object[] setContents)
public override async Task<bool> 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;
}
}
*/
}
}

View File

@@ -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<bool> ConnectAsync()
{
return await _baseConnector.ConnectAsync();
}
public bool Disconnect()
{
return _baseConnector.Disconnect();
@@ -40,9 +46,19 @@ namespace ModBus.Net
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
public virtual byte[] SendReceive(byte[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
}
/// <summary>
/// 发送并接收数据
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
public virtual async Task<byte[]> 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
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
public virtual byte[] SendReceiveWithoutExtAndDec(byte[] content)
{
return AsyncHelper.RunSync(() => SendReceiveWithoutExtAndDecAsync(content));
}
/// <summary>
/// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议
/// </summary>
/// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns>
public virtual async Task<byte[]> SendReceiveWithoutExtAndDecAsync(byte[] content)
{
//发送数据
byte[] receiveBytes = _baseConnector.SendMsg(content);
byte[] receiveBytes = await _baseConnector.SendMsgAsync(content);
//容错处理
if (!CheckRight(receiveBytes)) return null;
//返回字符

View File

@@ -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<byte[]> 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<OutputStruct> 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<OutputStruct> 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<bool> 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);
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 inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling,
_maxCalled,
_maxPdu);
var outputStruct2 =
(EstablishAssociationSimenseOutputStruct)
SendReceive(this[typeof (EstablishAssociationSimenseProtocal)], inputStruct2);
await
SendReceiveAsync(this[typeof (EstablishAssociationSimenseProtocal)],
inputStruct2);
return true;
});
}
return false;
}

View File

@@ -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<byte[]> 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<bool> 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();
}
*/
}
}

View File

@@ -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);