master
CaesarBao 3 months ago
parent fcc3882b60
commit e6502707c3

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
@ -228,6 +230,7 @@ namespace Mesnac.DeviceAdapter
/// <returns>1成功2为通讯成功设备未返回3为发送失败</returns>
byte Device_SendHeartPack();
Task<byte> Device_SendHeartPackAsync(CancellationToken cancellationToken = default);
/// <summary>
/// 获取自报数据
/// </summary>

@ -9,7 +9,7 @@
<appSettings>
<add key="CollectID" value="101" />
<!--<add key="SqlString" value="Persist Security Info=True;Password=123456;User ID=sa;Initial Catalog=WLDB;Data Source=127.0.0.1;Connection Timeout=5" />-->
<add key="SqlString" value="Persist Security Info=True;Password=haiwei@123;User ID=sa;Initial Catalog=XJMIDDBTOMES;Data Source=119.45.202.115;Connection Timeout=5" />
<add key="SqlString" value="Persist Security Info=True;Password=haiwei@123;User ID=sa;Initial Catalog=WLDB;Data Source=119.45.202.115;Connection Timeout=5" />
<add key="UpdateUrl" value="ftp://118.24.158.141" />
<!--定时删除日志时间间隔(单位:月)-->
<add key="DeleteLogIntervel" value="2" />

@ -38,6 +38,9 @@
<PropertyGroup>
<ApplicationIcon>cloud_computing_128px_1222169_easyicon.net.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="CatLib.Core">
<HintPath>dll\CatLib.Core.dll</HintPath>

@ -11,6 +11,7 @@
// public static string GetMesEquipList = "GetMesEquipList";
public static string UpdateMesListInfo = "UpdateMesListInfo";
public static string updateEquipListInfoasyc = "updateEquipListInfoasyc";
public static string updateEquipListInfo = "updateEquipListInfo";
public static string updateSensorListInfo = "updateSensorListInfo";

@ -137,6 +137,7 @@ namespace HighWayAssemble
App.TriggerHalt(EventSystem.AppClosed);
App.Off(EventSystem.UpdateViewList);
App.Off(EventSystem.UpdateMesListInfo);
App.Off(EventSystem.updateEquipListInfoasyc);
App.Off(EventSystem.updateEquipListInfo);
App.Off(EventSystem.updateSensorListInfo);
App.Off(EventSystem.MessageBox);
@ -161,6 +162,11 @@ namespace HighWayAssemble
{
view.UpdateMesListView(mesinfo);
});
App.On(EventSystem.updateEquipListInfoasyc, (DeviceInfo state) =>
{
view.equipState(state.m_iDeviceId.ToString(), state.m_ConnectState);
});
App.On(EventSystem.updateEquipListInfo, (List<DeviceInfo> state) =>
{
for (int i = 0; i < state.Count; i++)

@ -329,8 +329,14 @@ namespace HighWayAssemble
//发送传感器
m_EquipClient.SensorInfo(SoftInfo.SensorList);
m_EquipClient.Init();
//设备状态回调
m_EquipClient.RecEquipState(async (state) =>
m_EquipClient.RecEquipStateasyc(async (state) =>
{
App.TriggerHalt(EventSystem.updateEquipListInfoasyc, state);
});
//设备状态回调
m_EquipClient.RecEquipState(async (state) =>
{
App.TriggerHalt(EventSystem.updateEquipListInfo, state);
for (int i = 0; i < state.Count; i++)

@ -45,7 +45,7 @@ namespace HighWayAssemble.Protocol
}
catch (Exception ex)
{
FrmDisplayView.LogInfo.Error("ERROR: " + ex.Message);
FrmDisplayView.LogInfo.Fatal("MES接口连接异常: " + ex.Message);
}
}
@ -63,7 +63,7 @@ namespace HighWayAssemble.Protocol
}
catch (Exception ex)
{
FrmDisplayView.LogInfo.Error("ERROR: " + ex.Message);
FrmDisplayView.LogInfo.Fatal("MES接口调用异常: " + ex.Message);
return null;
}
}

@ -0,0 +1,238 @@
using log4net.Core;
using Mesnac.DeviceAdapter.RFly_I160;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Highway.Assemble.EquipClient
{
using Highway.Assemble.common;
using Mesnac.DeviceAdapterNet;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public class DeviceHeartbeatManager : IDisposable
{
private readonly ConcurrentDictionary<string, CancellationTokenSource> _deviceTokens =
new ConcurrentDictionary<string, CancellationTokenSource>();
private List<DeviceInfo> _deviceIds;
private readonly SemaphoreSlim _concurrencySemaphore;
private readonly int _heartbeatIntervalMs;
private readonly int _timeoutMs;
private readonly ILogger _logger;
private readonly Func<string, MessagePack> _createHeartbeatMessage;
private readonly Func<string, MessagePack, Task<bool>> _sendMessageAsync;
private readonly Action<string, byte> _handleResult;
private Timer _heartbeatTimer;
private bool _isDisposed;
public DeviceHeartbeatManager(
int maxConcurrentDevices = 10,
int heartbeatIntervalMs = 2000,
int timeoutMs = 2000,
ILogger logger = null,
Func<string, MessagePack> createHeartbeatMessage = null,
Func<string, MessagePack, Task<bool>> sendMessageAsync = null,
Action<string, byte> handleResult = null)
{
_concurrencySemaphore = new SemaphoreSlim(maxConcurrentDevices);
_heartbeatIntervalMs = heartbeatIntervalMs;
_timeoutMs = timeoutMs;
_logger = logger ?? new NullLogger();
_createHeartbeatMessage = createHeartbeatMessage ?? CreateDefaultHeartbeatMessage;
_sendMessageAsync = sendMessageAsync ?? ((id, msg) => Task.FromResult(false));
_handleResult = handleResult ?? ((id, result) => { });
}
public void StartMonitoring(List<DeviceInfo> deviceIds)
{
if (_heartbeatTimer != null)
throw new InvalidOperationException("Heartbeat manager is already running.");
_deviceIds = deviceIds;
// 创建定时器,使用固定间隔触发心跳周期
_heartbeatTimer = new Timer(
callback: ExecuteHeartbeatCycle,
state: null,
dueTime: 0,
period: _heartbeatIntervalMs);
}
public void StopMonitoring()
{
if (_heartbeatTimer == null)
return;
_heartbeatTimer.Dispose();
_heartbeatTimer = null;
// 取消所有正在执行的设备任务
foreach (var cts in _deviceTokens.Values)
{
cts.Cancel();
cts.Dispose();
}
_deviceTokens.Clear();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_isDisposed)
return;
if (disposing)
{
StopMonitoring();
_concurrencySemaphore.Dispose();
}
_isDisposed = true;
}
private async void ExecuteHeartbeatCycle(object state)
{
try
{
var cycleStartTime = DateTime.UtcNow;
_logger.Debug($"Starting heartbeat cycle at {cycleStartTime:O}");
// 为每个设备创建独立的取消令牌
var deviceTasks = new List<Task>();
foreach (var deviceId in _deviceIds)
{
var cts = new CancellationTokenSource();
_deviceTokens.AddOrUpdate(deviceId.m_iDeviceId.ToString(), cts, (key, oldValue) => { oldValue.Dispose(); return cts; });
deviceTasks.Add(SendHeartbeatAsync(deviceId.m_iDeviceId.ToString(), cts.Token));
}
// 并发执行所有设备的心跳任务
await Task.WhenAll(deviceTasks);
var cycleDuration = (DateTime.UtcNow - cycleStartTime).TotalMilliseconds;
_logger.Debug($"Heartbeat cycle completed in {cycleDuration:F2}ms");
}
catch (OperationCanceledException)
{
_logger.Info("Heartbeat cycle was canceled.");
}
catch (Exception ex)
{
_logger.Error($"Exception in heartbeat cycle: {ex.Message}");
}
}
private async Task SendHeartbeatAsync(string deviceId, CancellationToken cancellationToken)
{
await _concurrencySemaphore.WaitAsync(cancellationToken);
try
{
var startTime = DateTime.UtcNow;
_logger.Debug($"Sending heartbeat to device {deviceId} at {startTime:O}");
var message = _createHeartbeatMessage(deviceId);
var result = await SendWithTimeoutAsync(deviceId, message, cancellationToken);
_handleResult(deviceId, result);
var elapsed = (DateTime.UtcNow - startTime).TotalMilliseconds;
_logger.Debug($"Heartbeat to device {deviceId} processed in {elapsed:F2}ms");
}
catch (OperationCanceledException)
{
_handleResult(deviceId, 2); // 操作取消
}
catch (Exception ex)
{
_logger.Error($"Exception sending heartbeat to device {deviceId}: {ex.Message}");
_handleResult(deviceId, 2); // 发生异常
}
finally
{
_concurrencySemaphore.Release();
// 清理完成的任务令牌
if (_deviceTokens.TryGetValue(deviceId, out var cts) && !cts.IsCancellationRequested)
{
cts.Dispose();
_deviceTokens.TryRemove(deviceId, out _);
}
}
}
private async Task<byte> SendWithTimeoutAsync(string deviceId, MessagePack message, CancellationToken cancellationToken)
{
using (var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
timeoutCts.CancelAfter(_timeoutMs);
try
{
var sendTask = _sendMessageAsync(deviceId, message);
var completedTask = await Task.WhenAny(sendTask, Task.Delay(Timeout.Infinite, timeoutCts.Token));
if (completedTask == sendTask)
{
return await sendTask ? (byte)1 : (byte)2;
}
_logger.Warn($"Heartbeat to device {deviceId} timed out after {_timeoutMs}ms");
return 0; // 超时
}
catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
{
_logger.Warn($"Heartbeat to device {deviceId} timed out after {_timeoutMs}ms");
return 0; // 超时
}
}
}
private MessagePack CreateDefaultHeartbeatMessage(string deviceId)
{
return new MessagePack
{
m_pData = new byte[9] { 0xAA, 0x55, 0x00, 0x90, 0x90, 0x0D, 0x00, 0x00, 0x0D }
};
}
}
// 简单的日志接口实现
public interface ILogger
{
void Debug(string message);
void Info(string message);
void Warn(string message);
void Error(string message);
}
public class NullLogger : ILogger
{
public void Debug(string message) { }
public void Info(string message) { }
public void Warn(string message) { }
public void Error(string message) { }
}
// 消息包结构
public class MessagePack
{
public byte[] m_pData { get; set; }
}
}

@ -19,6 +19,9 @@ namespace Highway.Assemble.EquipClient
public Action<List<DeviceInfo>> EquipStateAction;
public Action<DeviceInfo> EquipStateActionasyc;
public Action<string, List<TagInfo>> ReadDataAction;
public Action<string, List<TagInfo>> RecSendDataAction;
@ -129,15 +132,242 @@ namespace Highway.Assemble.EquipClient
LogInfo.Info("设备信息表为空!");
return;
}
m_bgwDeviceDetect.DoWork += bgwDeviceDetect_DoWork;
m_bgwDeviceDetect.RunWorkerAsync(this);
}
//private void test()
//{
// // 创建心跳管理器实例
// var manager = new DeviceHeartbeatManager(
// maxConcurrentDevices: 10, // 最大并发设备数
// heartbeatIntervalMs: 2000, // 心跳间隔(毫秒)
// timeoutMs: 2000, // 超时时间(毫秒)
// sendMessageAsync: async (deviceId, message) =>
// {
// // 实际发送心跳包的逻辑
// try
// {
// // 这里调用你的通信服务发送消息
// return await YourCommunicationService.SendAsync(deviceId, message);
// }
// catch
// {
// return false;
// }
// },
// handleResult: (deviceId, result) =>
// {
// // 处理心跳结果
// switch (result)
// {
// case 0: Console.WriteLine($"Device {deviceId} timed out"); break;
// case 1: Console.WriteLine($"Device {deviceId} is online"); break;
// case 2: Console.WriteLine($"Device {deviceId} communication error"); break;
// }
// }
// );
// // 添加设备进行监控
// manager.StartMonitoring(m_DeviceInfoList);
// // 稍后停止监控
// // manager.StopMonitoring();
//}
private async void bgwDeviceDetect_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker backgroundworker = sender as BackgroundWorker;
CancellationTokenSource cts = new CancellationTokenSource();
const int DETECTION_INTERVAL_MS = 30000; // 检测间隔1分钟
try
{
// 记录下一次检测的时间点
DateTime nextDetectionTime = DateTime.Now.AddMilliseconds(DETECTION_INTERVAL_MS);
while (!ExitEvent.WaitOne(0, exitContext: false))
{
try
{
Console.WriteLine(DateTime.Now+"开始执行设备检测");
// 执行设备检测
await PerformDeviceDetection(cts.Token);
}
catch (OperationCanceledException)
{
// 任务被取消,退出循环
break;
}
catch (Exception ex)
{
LogInfo.Error("设备检测过程中发生异常: " + ex.Message);
}
// 计算距离下一次检测的剩余时间
TimeSpan timeToNextDetection = nextDetectionTime - DateTime.Now;
// 如果剩余时间为正,则等待
if (timeToNextDetection > TimeSpan.Zero)
{
await Task.Delay(timeToNextDetection, cts.Token);
}
// 设置下一次检测时间点
nextDetectionTime = DateTime.Now.AddMilliseconds(DETECTION_INTERVAL_MS);
}
LogInfo.Info("设备检测线程正常退出");
ExitEvent.Reset();
e.Cancel = true;
}
catch (OperationCanceledException)
{
LogInfo.Info("设备检测线程被取消");
}
catch (Exception ex)
{
LogInfo.Error("设备检测线程异常:" + ex.Message);
// 异常发生后等待一段时间再继续
await Task.Delay(30000);
}
finally
{
cts.Cancel();
cts.Dispose();
}
}
// 执行所有设备的检测
private async Task PerformDeviceDetection(CancellationToken cancellationToken)
{
var tasks = new List<Task>();
SemaphoreSlim semaphore = new SemaphoreSlim(m_DeviceInfoList.Count); // 限制最多5个并发任务
foreach (var item in m_DeviceInfoList)
{
await semaphore.WaitAsync(cancellationToken);
tasks.Add(Task.Factory.StartNew(async () =>
{
try
{
await HandleDeviceConnection(item);
// 更新设备状态
EquipStateActionasyc?.Invoke(item);
}
catch (OperationCanceledException)
{
// 任务被取消
}
catch (Exception ex)
{
LogInfo.Error($"处理设备 {item.m_strConnectStr} 时出错: {ex.Message}");
}
finally
{
semaphore.Release();
}
}, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap());
}
// 等待所有任务完成
await Task.WhenAll(tasks);
}
// 其余方法保持不变...
// 将设备连接处理逻辑提取为单独的方法
private async Task HandleDeviceConnection(DeviceInfo item)
{
IDeviceAdapter pDeviceAdapter = item.m_IDeviceAdapter;
if (pDeviceAdapter == null)
{
item.m_ConnectState = 0;
return;
}
if (item.m_iDeviceId == 10001)
{
}
switch (item.m_ConnectState)
{
case 0: // 未连接状态
if (await RunOnThreadPool(() => pDeviceAdapter.Device_Init_Id((CommType)item.m_iConnectMode, item.m_strConnectStr, item.m_iDeviceId)))
{
if (await RunOnThreadPool(() => pDeviceAdapter.Device_Connect()))
{
// 管理事件订阅,避免重复订阅
pDeviceAdapter.RecvIdentifyDataEvent -= RecvIdentifyData_Instance;
pDeviceAdapter.RecvIdentifyDataEvent += RecvIdentifyData_Instance;
item.m_ConnectState = await GetConnectionStateFromHeartbeat(pDeviceAdapter);
}
else
{
item.m_ConnectState = 0;
}
}
else
{
item.m_ConnectState = 0;
}
break;
case 1: // 已连接状态
item.m_ConnectState = await GetConnectionStateFromHeartbeat(pDeviceAdapter);
break;
case 2: // 连接异常状态
int heartbeatResult = await GetConnectionStateFromHeartbeat(pDeviceAdapter);
if (heartbeatResult == 2)
{
item.m_ConnectState = 0;
await RunOnThreadPool(() => item.m_IDeviceAdapter.Device_Destroy());
}
else if (heartbeatResult == 1)
{
item.m_ConnectState = 1;
}
else
{
item.m_ConnectState = 0;
await RunOnThreadPool(() => item.m_IDeviceAdapter.Device_Destroy());
}
break;
}
}
// 将心跳检测逻辑提取为单独的方法
private async Task<byte> GetConnectionStateFromHeartbeat(IDeviceAdapter adapter)
{
return await adapter.Device_SendHeartPackAsync();
}
// 替代 Task.Run 的辅助方法,兼容 .NET Framework 4.6.1
private Task<T> RunOnThreadPool<T>(Func<T> func)
{
return Task.Factory.StartNew(func, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
// 替代 Task.Run 的辅助方法,兼容 .NET Framework 4.6.1
private Task RunOnThreadPool(Action action)
{
return Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
/// <summary>
/// 监听设备数据事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void bgwDeviceDetect_DoWork(object sender, DoWorkEventArgs e)
private void bgwDeviceDetect_DoWork(object sender, DoWorkEventArgs e ,string test)
{
BackgroundWorker backgroundworker = sender as BackgroundWorker;
while (true)
@ -229,7 +459,7 @@ namespace Highway.Assemble.EquipClient
});
}
DetectEvent.Reset();
DetectEvent.WaitOne(120000, exitContext: false);
DetectEvent.WaitOne(60000, exitContext: false);
}
catch (Exception ex)
{
@ -722,6 +952,11 @@ namespace Highway.Assemble.EquipClient
EquipStateAction = action;
}
public void RecEquipStateasyc(Action<DeviceInfo> action)
{
EquipStateActionasyc = action;
}
public void RecGetData(Action<int, int, int> action)
{
RecGetDataAction = action;

@ -49,6 +49,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConcurrentDeviceHeartbeatManager.cs" />
<Compile Include="DeviceInfo.cs" />
<Compile Include="EquipClient.cs" />
<Compile Include="IEquipClient.cs" />
@ -63,6 +64,10 @@
<Project>{514b888f-4d0d-4406-9396-5235a7bed7bf}</Project>
<Name>Highway.Assemble.Common</Name>
</ProjectReference>
<ProjectReference Include="..\Mesnac.DeviceAdapter.RFly_I160\Mesnac.DeviceAdapter.RFly_I160.csproj">
<Project>{786B9D51-D67A-4235-B082-78E9CF4FCFB6}</Project>
<Name>Mesnac.DeviceAdapter.RFly_I160</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

@ -27,6 +27,8 @@ namespace Highway.Assemble.EquipClient
void RecEquipState(Action<List<DeviceInfo>> action);
void RecEquipStateasyc(Action<DeviceInfo> action);
void ReadData(int num, byte filterMembank, ushort filterWordPtr, ushort filterWordCnt, byte[] filterData, byte Membank, ushort WordPtr, ushort WordCnt);
void RetReadData(Action<string, List<TagInfo>> action);

@ -4,6 +4,7 @@ using System.ComponentModel;
//using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Mesnac.DeviceAdapter.Fuchs
{
@ -1508,6 +1509,11 @@ namespace Mesnac.DeviceAdapter.Fuchs
throw new NotImplementedException();
}
public Task<byte> Device_SendHeartPackAsync(CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
//public List<TagInfo> TagInventoryTimePeriod(byte Antenna, int time)
//{
// List<TagInfo> t = new List<TagInfo> { };

@ -4,6 +4,7 @@ using System.Configuration;
//using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Mesnac.DeviceAdapter.HWKC_81600
{
@ -784,6 +785,11 @@ namespace Mesnac.DeviceAdapter.HWKC_81600
{
throw new NotImplementedException();
}
public Task<byte> Device_SendHeartPackAsync(CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
#endregion
}
}

@ -284,7 +284,7 @@ namespace Mesnac.DeviceAdapter.RFly_I160
m_ClientSock.Blocking = false;
m_ClientSock.Send(tmp, 0, 0);
bResult = true;
Console.WriteLine("Connected!");
//Console.WriteLine("Connected!");
}
else
{
@ -297,12 +297,12 @@ namespace Mesnac.DeviceAdapter.RFly_I160
if (e.NativeErrorCode.Equals(10035))
{
bResult = true;
Console.WriteLine("Still Connected, but the Send would block");
//Console.WriteLine("Still Connected, but the Send would block");
}
else
{
bResult = false;
Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
//Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
}
}
finally

@ -1,12 +1,13 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
//using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Configuration;
using System.Collections;
using System.Threading.Tasks;
namespace Mesnac.DeviceAdapter.RFly_I160
{
@ -34,7 +35,10 @@ namespace Mesnac.DeviceAdapter.RFly_I160
private Semaphore m_GlobalSem = new Semaphore(1, 1);
private bool m_GetHeartSuccessful = false;
private Semaphore m_GetHeartSem = new Semaphore(0, 100000);
private Semaphore m_GetHeartSem = new Semaphore(0, 100000);
//private ManualResetEvent m_GetHeartSem = new ManualResetEvent(false);
private Semaphore m_MulEpcSem = new Semaphore(0, 100000);
private Semaphore m_StopSem = new Semaphore(0, 100000);
@ -272,6 +276,94 @@ namespace Mesnac.DeviceAdapter.RFly_I160
return true;
}
public async Task<byte> Device_SendHeartPackAsync(CancellationToken cancellationToken = default)
{
try
{
// 使用 ManualResetEventSlim 替代 SemaphoreSlim支持异步等待
await Task.Factory.StartNew(
() => m_GlobalSem.WaitOne(),
cancellationToken,
TaskCreationOptions.None,
TaskScheduler.Default
);
// 创建心跳包
var messagePack = new MessagePack
{
m_pData = new byte[9] { 0xAA, 0x55, 0x00, 0x90, 0x90, 0x0D, 0x00, 0x00, 0x0D }
};
// 检查通信服务
if (m_ICommunicateService == null)
{
LogInfo.Error("Communication service is not initialized.");
return 2; // 通讯连接器失败或网络故障
}
// 发送心跳包
bool sendSuccess = await Task.Factory.StartNew(
() => m_ICommunicateService.SendMessage(messagePack),
cancellationToken,
TaskCreationOptions.None,
TaskScheduler.Default
);
if (!sendSuccess)
{
LogInfo.Warn("Failed to send heartbeat message.");
return 2; // 通讯连接器失败或网络故障
}
// 使用 WaitHandle.WaitOne 的超时机制
var waitTask = Task.Factory.StartNew(
() => m_GetHeartSem.WaitOne(2000, false),
cancellationToken,
TaskCreationOptions.None,
TaskScheduler.Default
);
// 不需要第二个超时,直接等待任务完成
await waitTask;
if (waitTask.Result)
{
LogInfo.Debug("Heartbeat response received successfully.");
return 1; // 通讯连接和读写器都正常
}
else
{
// 处理超时的情况
LogInfo.Warn("Heartbeat response timed out after 2000ms.");
return 0; // 或者抛出异常,取决于你的需求
}
}
catch (OperationCanceledException)
{
LogInfo.Info("Heartbeat operation was canceled.");
return 2;
}
catch (Exception ex)
{
LogInfo.Error($"Exception in Device_SendHeartPackAsync: {ex.Message}");
return 2; // 发生异常,返回通讯故障
}
finally
{
// 确保信号量总是被释放
try
{
m_GlobalSem.Release();
}
catch (ApplicationException)
{
LogInfo.Error("Global semaphore was already released.");
}
}
}
public byte Device_SendHeartPack()
{
byte iResult = 0;

Loading…
Cancel
Save