2018-01-04 Update 1 Add Siemens Connection AsyncLock
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Configuration;
|
||||
using System.Threading.Tasks;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace Modbus.Net.Siemens
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace Modbus.Net.Siemens
|
||||
public class SiemensPpiProtocol : SiemensProtocol
|
||||
{
|
||||
private readonly string _com;
|
||||
private readonly AsyncLock _lock = new AsyncLock();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@@ -71,15 +73,17 @@ namespace Modbus.Net.Siemens
|
||||
/// </summary>
|
||||
/// <returns>是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
IOutputStruct outputStruct;
|
||||
using (await _lock.LockAsync())
|
||||
{
|
||||
if (ProtocolLinker.IsConnected) return true;
|
||||
if (!await ProtocolLinker.ConnectAsync()) return false;
|
||||
var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress);
|
||||
var outputStruct =
|
||||
outputStruct =
|
||||
(await (await
|
||||
ForceSendReceiveAsync(this[typeof(ComCreateReferenceSiemensProtocol)],
|
||||
inputStruct)).
|
||||
SendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocol)], answer =>
|
||||
inputStruct)).SendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocol)], answer =>
|
||||
answer != null
|
||||
? new ComConfirmMessageSiemensInputStruct(SlaveAddress, MasterAddress)
|
||||
: null)).Unwrap<ComConfirmMessageSiemensOutputStruct>();
|
||||
@@ -87,6 +91,7 @@ namespace Modbus.Net.Siemens
|
||||
{
|
||||
ProtocolLinker.Disconnect();
|
||||
}
|
||||
}
|
||||
return outputStruct != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Configuration;
|
||||
using System.Threading.Tasks;
|
||||
using Nito.AsyncEx;
|
||||
|
||||
namespace Modbus.Net.Siemens
|
||||
{
|
||||
@@ -17,6 +18,7 @@ namespace Modbus.Net.Siemens
|
||||
private readonly byte _tdpuSize;
|
||||
private readonly ushort _tsapDst;
|
||||
private int _connectTryCount;
|
||||
private readonly AsyncLock _lock = new AsyncLock();
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@@ -142,25 +144,31 @@ namespace Modbus.Net.Siemens
|
||||
/// </summary>
|
||||
/// <returns>设备是否连接成功</returns>
|
||||
public override async Task<bool> ConnectAsync()
|
||||
{
|
||||
IOutputStruct outputStruct;
|
||||
using (await _lock.LockAsync())
|
||||
{
|
||||
_connectTryCount++;
|
||||
if (ProtocolLinker.IsConnected) return true;
|
||||
if (!await ProtocolLinker.ConnectAsync()) return false;
|
||||
_connectTryCount = 0;
|
||||
var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst);
|
||||
var outputStruct =
|
||||
outputStruct =
|
||||
//先建立连接,然后建立设备的引用
|
||||
(await (await
|
||||
ForceSendReceiveAsync(this[typeof(CreateReferenceSiemensProtocol)], inputStruct)).SendReceiveAsync(
|
||||
ForceSendReceiveAsync(this[typeof(CreateReferenceSiemensProtocol)], inputStruct))
|
||||
.SendReceiveAsync(
|
||||
this[typeof(EstablishAssociationSiemensProtocol)], answer =>
|
||||
answer != null ?
|
||||
new EstablishAssociationSiemensInputStruct(0x0101, _maxCalling,
|
||||
answer != null
|
||||
? new EstablishAssociationSiemensInputStruct(0x0101, _maxCalling,
|
||||
_maxCalled,
|
||||
_maxPdu) : null)).Unwrap<EstablishAssociationSiemensOutputStruct>();
|
||||
_maxPdu)
|
||||
: null)).Unwrap<EstablishAssociationSiemensOutputStruct>();
|
||||
if (outputStruct == null && ProtocolLinker.IsConnected)
|
||||
{
|
||||
ProtocolLinker.Disconnect();
|
||||
}
|
||||
}
|
||||
return outputStruct != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,9 +401,10 @@ namespace Modbus.Net
|
||||
/// <param name="returnFunc">返回值的处理函数</param>
|
||||
/// <param name="getDataType">返回值的键类型</param>
|
||||
/// <param name="timeout">任务的超时时间</param>
|
||||
public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int timeout = 100000)
|
||||
/// <param name="reName">重命名,对单个设备使用多个GetData时必须填写不同的字符串</param>
|
||||
public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int timeout = 100000, string reName = null)
|
||||
{
|
||||
Name = "GetDatas";
|
||||
Name = reName ?? "GetDatas";
|
||||
TimeoutTime = timeout;
|
||||
Invoke = async (machine, tasks, parameters, timeoutTime) =>
|
||||
{
|
||||
@@ -442,8 +443,9 @@ namespace Modbus.Net
|
||||
/// <param name="getCycle">循环间隔(毫秒)</param>
|
||||
/// <param name="sleepCycle">设备离线时的循环间隔(毫秒)</param>
|
||||
/// <param name="timeout">任务的超时时间</param>
|
||||
/// <param name="reName">重命名,对单个设备使用多个GetData时必须填写不同的字符串</param>
|
||||
public TaskItemGetData(Action<DataReturnDef> returnFunc, MachineGetDataType getDataType, int getCycle,
|
||||
int sleepCycle, int timeout = 100000) : this(returnFunc, getDataType, timeout)
|
||||
int sleepCycle, int timeout = 100000, string reName = null) : this(returnFunc, getDataType, timeout, reName)
|
||||
{
|
||||
TimerDisconnectedTime = sleepCycle;
|
||||
TimerTime = getCycle;
|
||||
@@ -462,9 +464,10 @@ namespace Modbus.Net
|
||||
/// <param name="setDataType">写入值的键类型</param>
|
||||
/// <param name="returnFunc">返回值的处理函数</param>
|
||||
/// <param name="timeout">任务的超时时间</param>
|
||||
public TaskItemSetData(Func<Dictionary<string, double>> values, MachineSetDataType setDataType, int timeout = 100000, Action<bool> returnFunc = null)
|
||||
/// <param name="reName">重命名,对单个设备使用多个GetData时必须填写不同的字符串</param>
|
||||
public TaskItemSetData(Func<Dictionary<string, double>> values, MachineSetDataType setDataType, int timeout = 100000, Action<bool> returnFunc = null, string reName = null)
|
||||
{
|
||||
Name = "SetDatas";
|
||||
Name = reName ?? "SetDatas";
|
||||
TimeoutTime = timeout;
|
||||
Invoke = async (machine, tasks, parameters, timeoutTime) =>
|
||||
{
|
||||
@@ -499,9 +502,10 @@ namespace Modbus.Net
|
||||
/// <param name="getCycle">循环间隔(毫秒)</param>
|
||||
/// <param name="sleepCycle">设备离线时的循环间隔(毫秒)</param>
|
||||
/// <param name="timeout">任务的超时时间</param>
|
||||
/// <param name="reName">重命名,对单个设备使用多个GetData时必须填写不同的字符串</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)
|
||||
int sleepCycle, int timeout = 100000, Action<bool> returnFunc = null, string reName = null)
|
||||
: this(values, setDataType, timeout, returnFunc, reName)
|
||||
{
|
||||
TimerDisconnectedTime = sleepCycle;
|
||||
TimerTime = getCycle;
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace Modbus.Net
|
||||
{
|
||||
if (_socketClient.Connected)
|
||||
{
|
||||
_socketClient?.GetStream().Dispose();
|
||||
_socketClient.GetStream().Dispose();
|
||||
}
|
||||
_socketClient?.Close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user