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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace ModBus.Net namespace ModBus.Net
{ {
@@ -53,17 +54,22 @@ namespace ModBus.Net
KeepConnect = keepConnect; KeepConnect = keepConnect;
} }
public Dictionary<string,ReturnUnit> GetDatas() public Dictionary<string, ReturnUnit> GetDatas()
{
return AsyncHelper.RunSync(GetDatasAsync);
}
public async Task<Dictionary<string,ReturnUnit>> GetDatasAsync()
{ {
Dictionary<string, ReturnUnit> ans = new Dictionary<string, ReturnUnit>(); Dictionary<string, ReturnUnit> ans = new Dictionary<string, ReturnUnit>();
if (!BaseUtility.IsConnected) if (!BaseUtility.IsConnected)
{ {
BaseUtility.Connect(); await BaseUtility.ConnectAsync();
} }
if (!BaseUtility.IsConnected) return null; if (!BaseUtility.IsConnected) return null;
foreach (var communicateAddress in CommunicateAddresses) 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; if (datas == null || datas.Length == 0) return null;
int pos = 0; int pos = 0;
while (pos < communicateAddress.GetCount) while (pos < communicateAddress.GetCount)
@@ -94,6 +100,11 @@ namespace ModBus.Net
return BaseUtility.Connect(); return BaseUtility.Connect();
} }
public async Task<bool> ConnectAsync()
{
return await BaseUtility.ConnectAsync();
}
public bool Disconnect() public bool Disconnect()
{ {
return BaseUtility.Disconnect(); return BaseUtility.Disconnect();

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
namespace ModBus.Net namespace ModBus.Net
{ {
@@ -62,6 +63,16 @@ namespace ModBus.Net
return ProtocalLinker.SendReceive(ProtocalUnit.TranslateContent(content)); 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>
/// 发送协议,通过传入需要使用的协议内容和输入结构 /// 发送协议,通过传入需要使用的协议内容和输入结构
/// </summary> /// </summary>
@@ -92,12 +103,48 @@ namespace ModBus.Net
return null; 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>
/// 协议连接开始 /// 协议连接开始
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public abstract bool Connect(); public abstract bool Connect();
/// <summary>
/// 协议连接开始(异步)
/// </summary>
/// <returns></returns>
public abstract Task<bool> ConnectAsync();
/// <summary> /// <summary>
/// 协议连接断开 /// 协议连接断开
/// </summary> /// </summary>

View File

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

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
internal enum ModbusProtocalVariableFunctionCode : byte internal enum ModbusProtocalVariableFunctionCode : byte
{ {
@@ -44,6 +45,11 @@ namespace ModBus.Net
{ {
return ProtocalLinker.Connect(); return ProtocalLinker.Connect();
} }
public override async Task<bool> ConnectAsync()
{
return await ProtocalLinker.ConnectAsync();
}
} }
#region PLC数据 #region PLC数据

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
/// <summary> /// <summary>
/// Modbus连接类型 /// Modbus连接类型
@@ -65,13 +66,13 @@ namespace ModBus.Net
ModbusType = (ModbusType) connectionType; 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 try
{ {
var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress, getByteCount % 2 == 0 ? (ushort)(getByteCount / 2) : (ushort)(getByteCount / 2 + 1), AddressTranslator); var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress, getByteCount % 2 == 0 ? (ushort)(getByteCount / 2) : (ushort)(getByteCount / 2 + 1), AddressTranslator);
var outputStruct = var outputStruct = await
Wrapper.SendReceive(Wrapper[typeof(ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct; Wrapper.SendReceiveAsync(Wrapper[typeof(ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct;
return outputStruct.DataValue; return outputStruct.DataValue;
} }
catch 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 try
{ {
var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents, AddressTranslator); var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents, AddressTranslator);
var outputStruct = var outputStruct = await
Wrapper.SendReceive(Wrapper[typeof(WriteDataModbusProtocal)], inputStruct) as Wrapper.SendReceiveAsync(Wrapper[typeof(WriteDataModbusProtocal)], inputStruct) as
WriteDataModbusOutputStruct; WriteDataModbusOutputStruct;
if (outputStruct.WriteCount != setContents.Length) return false; if (outputStruct.WriteCount != setContents.Length) return false;
return true; return true;
@@ -97,6 +98,7 @@ namespace ModBus.Net
} }
} }
/*
public override DateTime GetTime(byte belongAddress) public override DateTime GetTime(byte belongAddress)
{ {
try try
@@ -128,5 +130,6 @@ namespace ModBus.Net
return false; return false;
} }
} }
*/
} }
} }

View File

@@ -1,4 +1,5 @@
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
namespace ModBus.Net namespace ModBus.Net
{ {
@@ -29,6 +30,11 @@ namespace ModBus.Net
return _baseConnector.Connect(); return _baseConnector.Connect();
} }
public async Task<bool> ConnectAsync()
{
return await _baseConnector.ConnectAsync();
}
public bool Disconnect() public bool Disconnect()
{ {
return _baseConnector.Disconnect(); return _baseConnector.Disconnect();
@@ -40,9 +46,19 @@ namespace ModBus.Net
/// <param name="content">发送协议的内容</param> /// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns> /// <returns>接收协议的内容</returns>
public virtual byte[] SendReceive(byte[] content) 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[] extBytes = BytesExtend(content);
byte[] receiveBytes = SendReceiveWithoutExtAndDec(extBytes); byte[] receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
return receiveBytes == null ? null : BytesDecact(receiveBytes); return receiveBytes == null ? null : BytesDecact(receiveBytes);
} }
@@ -52,9 +68,19 @@ namespace ModBus.Net
/// <param name="content">发送协议的内容</param> /// <param name="content">发送协议的内容</param>
/// <returns>接收协议的内容</returns> /// <returns>接收协议的内容</returns>
public virtual byte[] SendReceiveWithoutExtAndDec(byte[] content) 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; if (!CheckRight(receiveBytes)) return null;
//返回字符 //返回字符

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
namespace ModBus.Net namespace ModBus.Net
{ {
@@ -31,45 +32,68 @@ namespace ModBus.Net
} }
public override byte[] SendReceive(params object[] content) public override byte[] SendReceive(params object[] content)
{
return AsyncHelper.RunSync(() => SendReceiveAsync(content));
}
public override async Task<byte[]> SendReceiveAsync(params object[] content)
{ {
while (!ProtocalLinker.IsConnected) while (!ProtocalLinker.IsConnected)
{ {
Connect(); await ConnectAsync();
} }
return base.SendReceive(content); return await base.SendReceiveAsync(content);
} }
public override OutputStruct SendReceive(ProtocalUnit unit, InputStruct 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 (!ProtocalLinker.IsConnected)
{ {
if (connectTryCount > 10) return null; 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() public override bool Connect()
{
return AsyncHelper.RunSync(ConnectAsync);
}
public override async Task<bool> ConnectAsync()
{ {
connectTryCount++; connectTryCount++;
ProtocalLinker = new SimenseTcpProtocalLinker(_ip); ProtocalLinker = new SimenseTcpProtocalLinker(_ip);
if (ProtocalLinker.Connect()) if (await ProtocalLinker.ConnectAsync())
{ {
connectTryCount = 0;
var inputStruct = new CreateReferenceSimenseInputStruct(_tdpuSize, _taspSrc, _tsapDst); var inputStruct = new CreateReferenceSimenseInputStruct(_tdpuSize, _taspSrc, _tsapDst);
var outputStruct = return
(CreateReferenceSimenseOutputStruct) await await
ForceSendReceive(this[typeof (CreateReferenceSimenseProtocal)], inputStruct); ForceSendReceiveAsync(this[typeof (CreateReferenceSimenseProtocal)], inputStruct)
if (!ProtocalLinker.IsConnected) return false; .ContinueWith(async answer =>
var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling, _maxCalled, _maxPdu); {
var outputStruct2 = if (!ProtocalLinker.IsConnected) return false;
(EstablishAssociationSimenseOutputStruct) var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling,
SendReceive(this[typeof (EstablishAssociationSimenseProtocal)], inputStruct2); _maxCalled,
return true; _maxPdu);
var outputStruct2 =
(EstablishAssociationSimenseOutputStruct)
await
SendReceiveAsync(this[typeof (EstablishAssociationSimenseProtocal)],
inputStruct2);
return true;
});
} }
return false; return false;
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
public enum SimenseType public enum SimenseType
{ {
@@ -105,31 +106,30 @@ namespace ModBus.Net
ConnectionType = (SimenseType) connectionType; 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 try
{ {
var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xd3c7, SimenseTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator); var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xd3c7, SimenseTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSimenseOutputStruct = var readRequestSimenseOutputStruct =
(ReadRequestSimenseOutputStruct) (ReadRequestSimenseOutputStruct) await
Wrapper.SendReceive(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct); Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct);
return readRequestSimenseOutputStruct.GetValue; return readRequestSimenseOutputStruct.GetValue;
} }
catch (Exception) catch (Exception)
{ {
return null; 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 try
{ {
var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xd3c8, startAddress, setContents, AddressTranslator); var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSimenseOutputStruct = var writeRequestSimenseOutputStruct =
(WriteRequestSimenseOutputStruct) (WriteRequestSimenseOutputStruct) await
Wrapper.SendReceive(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct); Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct);
if (writeRequestSimenseOutputStruct.AccessResult == SimenseAccessResult.NoError) if (writeRequestSimenseOutputStruct.AccessResult == SimenseAccessResult.NoError)
return true; return true;
else else
@@ -139,9 +139,9 @@ namespace ModBus.Net
{ {
return false; return false;
} }
} }
/*
public override DateTime GetTime(byte belongAddress) public override DateTime GetTime(byte belongAddress)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@@ -151,5 +151,6 @@ namespace ModBus.Net
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
*/
} }
} }

View File

@@ -425,8 +425,8 @@ namespace ModBus.Net
//var ans = machine.GetDatas(); //var ans = machine.GetDatas();
CancellationTokenSource cts = new CancellationTokenSource(); CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(_getCycle)); cts.CancelAfter(TimeSpan.FromSeconds(_getCycle));
var ans = await _tasks.StartNew(machine.GetDatas, cts.Token); var ans = await machine.GetDatasAsync().WithCancellation(cts.Token);
//var ans = await Task.Factory.StartNew(machine.GetDatas, cts.Token); //var ans = await machine.GetDatasAsync().WithCancellation(cts.Token);
if (!machine.IsConnected) if (!machine.IsConnected)
{ {
MoveMachineToUnlinked(machine.Id); MoveMachineToUnlinked(machine.Id);