secs_learn/Program.cs
此文件是应用程序的入口点,用于配置和启动主机。
- 使用
Host.CreateDefaultBuilder(args)
创建一个默认配置的主机构建器,自动加载环境变量、配置文件等设置。 .ConfigureServices(...)
方法中,通过services.AddHostedService<DeviceWorker>()
注册DeviceWorker
类型作为托管服务,这样在主机启动时会自动实例化并运行这个服务。- 最后,
.Build().Run();
构建并启动主机,执行注册的服务(在这里即为DeviceWorker
)。整个程序将持续运行,直到被显式停止或遇到不可恢复的错误。
using DeviceWorkerService; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<DeviceWorker>(); }).Build().Run();
secs_learn/DeviceWorker.cs
这个文件中定义了一个名为 DeviceWorker
的类,该类继承自 BackgroundService
类,这是 .NET Core 中用于创建长时间运行后台服务的基类。
ILogger<DeviceWorker>
:注入日志记录器,用于在服务执行过程中输出日志信息。ISecsConnection _hsmsConnection
:注入一个实现了ISecsConnection
接口的对象,它代表了与半导体设备之间的HSMS(High-Speed SECS Message Services)连接。ISecsGem _secsGem
:注入一个实现了ISecsGem
接口的对象,用于提供与遵循GEM规范的设备进行交互的方法。
在构造函数中,设置了 _hsmsConnection.ConnectionChanged
事件处理器,以便当连接状态改变时记录日志信息。
ExecuteAsync
方法是 BackgroundService
的核心方法,在服务启动后会被调用并持续执行,直到收到取消信号或者发生异常。在此方法内:
- 启动HSMS连接。
- 使用异步循环等待接收来自设备的主消息(Primary Message)。
- 对每一个接收到的主消息,构建对应的次消息(Secondary Message)并尝试回复给设备,如果在这个过程中出现异常,则记录错误日志。
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Secs4Net; using System; using System.Threading; using System.Threading.Tasks; namespace DeviceWorkerService; internal sealed class DeviceWorker : BackgroundService { private readonly ILogger<DeviceWorker> _logger; private readonly ISecsConnection _hsmsConnection; private readonly ISecsGem _secsGem; public DeviceWorker(ILogger<DeviceWorker> logger, ISecsConnection hsmsConnection, ISecsGem secsGem) { _logger = logger; _hsmsConnection = hsmsConnection; _secsGem = secsGem; _hsmsConnection.ConnectionChanged += delegate { switch (_hsmsConnection.State) { case ConnectionState.Retry: _logger.LogError($"Connection loss, try to reconnect."); break; case ConnectionState.Connecting: case ConnectionState.Connected: _logger.LogWarning(_hsmsConnection.State.ToString()); break; default: _logger.LogInformation($"Connection state = {_hsmsConnection.State}"); break; } }; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { _hsmsConnection.Start(stoppingToken); await foreach (var e in _secsGem.GetPrimaryMessageAsync(stoppingToken)) { using var primaryMessage = e.PrimaryMessage; _logger.LogInformation($"Received primary message: {primaryMessage}"); try { using var secondaryMessage = new SecsMessage(primaryMessage.S, (byte)(primaryMessage.F + 1)) { SecsItem = primaryMessage.SecsItem, }; await e.TryReplyAsync(secondaryMessage, stoppingToken); } catch (Exception ex) { _logger.LogError(ex, "Exception occurred when processing primary message"); } } } catch (Exception ex) { if (stoppingToken.IsCancellationRequested) { return; } _logger.LogError(ex, "Unhandled exception occurred on primary messages processing"); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-01-23 tampermonkey 油猴脚本 博客园美化