C#上位机1ms级高精度定时任务

precisiontimer

安装扩展包

添加引用

 完整代码

using PrecisionTiming;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        //参考视频
        //https://www.bilibili.com/video/BV1fd4y1v7dK/?spm_id_from=333.999.0.0&vd_source=e821a225c7ba4a7b85e5aa6d013ac92e
        PrecisionTimer timer = new PrecisionTimer();
        private void button1_Click(object sender, EventArgs e)
        {
            //timer.SetInterval(1);
            //timer.SetPeriodic(1);
            //timer
            timer.SetInterval(5);
            //方法1
            //timer.SetAction(new Action(() => 
            //{
            //    Console.WriteLine(DateTime.Now.Millisecond.ToString());
            //}));
            //方法2
            //Action showMethod = print;
            //timer.SetAction(showMethod);
            //方法3            
            timer.SetAction(print);

            timer.Start();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer.Stop();
        }
        private void print()
        {
            Console.WriteLine(DateTime.Now.Millisecond.ToString());
        }
    }
}

运行效果

资源链接(保护现有库调用实现代码,和独立代码实现)

【免费】c#高精度毫秒定时器,实现windows高精度定时器功能资源-优快云文库icon-default.png?t=N7T8https://download.youkuaiyun.com/download/anlog/89290452

参考链接

高精度定时器的使用以及实现_c# precisiontimer-优快云博客icon-default.png?t=N7T8https://blog.youkuaiyun.com/i78i845/article/details/130220156

C#上位机1ms级高精度定时任务讲解_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1fd4y1v7dK/?spm_id_from=333.337.search-card.all.click&vd_source=e821a225c7ba4a7b85e5aa6d013ac92e

特此记录

anlog

2024年5月10日

<think>首先,用户的问题是关于在C#上位机中实现以准确的循环周期发送报文。他们提到“参考站内引用”,引用了三个来源:[^1],[^2],[^3]。这些引用似乎描述了如何发送报文和处理接收的逻辑,但没有直接解决定时循环发送的问题。我需要检查用户的引用:-引用[^1]:描述了如何解析报文并发送到服务器。它涉及将报文字符串转换为字节数组,然后发送。-引用[^2]:讲解了一个主函数逻辑,包括发送帧头、检测发送成功、接收报文,使用中断接收。-引用[^3]:描述了C#数据采集系统的功能,包括PLC采集、ModbusTcp、优化、配置文件等。用户的核心问题是如何“实现以准确的循环周期发送报文”,具体是关于定时循环发送报文。用户上一次的问题是我不能访问的,因为没有提供上下文,所以我只能基于当前消息。我的系统指令要求:-所有行内数学表达式使用$...$格式。-独立公式使用$$...$$格式。-LaTeX语法正确。-使用中文回答。-生成相关问题。-在引用的段落末尾添加引用标识。用户提到“参考站内引用”,所以我应该引用这些来源,如果有相关信息。但从内容看,引用[^1]处理了发送报文的基本代码,引用[^2]涉及发送和接收机制,引用[^3]更宽泛地描述功能。对于实现定时循环发送报文在C#中,我需要提供准确的信息。C#中常见的定时机制包括:1.**System.Threading.Timer**:用于在指定的时间间隔执行代码。2.**System.Timers.Timer**:类似于Timer,但事件驱动。3.**Task.Delay**:用于异步代码中实现延迟。4.**System.Windows.Forms.Timer**:用于WindowsForms应用,UI线程安全。5.**DispatcherTimer**:用于WPF应用。用户说“上位机”,可能指的是Windows桌面应用,所以可能是WindowsForms或WPF。我会假设通用场景。准确循环周期发送报文需要考虑以下因素:-**定时精度**:对于高精度,Timer或使用系统时钟。-**避免阻塞**:使用异步方法来防止UI冻结。-**处理报文内容**:基于用户引用[^1],发送报文涉及转换字节数组。结构回答:1.**理解问题**:简要重述用户需求。2.**提供解决方案**:描述方法,包括代码示例或步骤。3.**基于引用整合**:由于用户提供了引用,我应该引用相关部分。例如,引用[^1]展示了发送报文的代码,我可以结合到定时发送中。4.**代码示例**:给出C#代码片段来实现定时循环发送报文。5.**注意事项**:讨论准确性、精度问题。6.**生成相关问题**:在结束时,添加相关问题部分。格式要求:-使用中文回答。-行内数学:如果有任何数学表达式(如周期计算),使用$...$。但在这个主题中,可能没有数学表达式,除非涉及时间计算。-独立公式:如果需要。-添加引用标识:如果直接引用参考内容。用户指定“上述引用仅供参考”,并说“请尽可能多的参考用户上一次的问题和你的回答”,但我没有上一个对话的上下文。所以我只能基于当前内容。构建回答:-**介绍**:解释定时循环发送的重要性。-**方法**:-使用System.Timers.Timer或System.Threading.Timer。-结合报文发送逻辑。-参考引用[^1]的发送方法。-**代码示例**:提供简单的C#代码示例。-**注意事项**:讨论定时精度的改进,如使用Stopwatch。-**相关问题**:生成相关问题。代码必须使用单独的格式块,就像示例中一样。引用添加:当提到引用内容时,在段落末尾添加[^数字]。回答结构:1.开头重述问题。2.详细解释。3.代码示例。4.总结。5.相关问题。代码示例:```csharp//类似于引用[^1],但加入定时器privateSystem.Timers.Timertimer;publicvoidStartSending(intintervalMilliseconds){timer=newSystem.Timers.Timer(intervalMilliseconds);timer.Elapsed+=OnTimedEvent;timer.AutoReset=true;//设置为true以实现循环发送timer.Start();}privatevoidOnTimedEvent(objectsender,ElapsedEventArgse){//发送报文的代码,参考引用[^1]//例如:发送报文逻辑}```完整响应框架:-使用中文。</think> 在C#上位机应用中实现以准确的循环周期发送报文,关键在于使用可靠的定时机制结合报文发送逻辑,确保发送间隔稳定且不阻塞UI线程。参考您提供的引用([^1]演示报文转换与发送的基本实现,[^2]强调发送检测和中断接收的重要性,[^3]讨论系统优化如配置文件和定时采集),我会结合这些内容,提供完整解决方案。以下方法基于C#的 `System.Timers.Timer` 或 `System.Threading.Timer` 实现高精度循环发送,同时规避线程阻塞问题。 ### 1. **核心方法:使用定时器实现循环周期发送** 在C#中,定时循环发送报文可通过异步任务或事件驱动定时器实现。推荐使用 `System.Timers.Timer` 因为它支持UI线程同步,避免冻结应用;而 `System.Threading.Timer` 更轻量但需手动处理线程安全。核心步骤如下: - **初始化报文发送逻辑**:参考引用[^1],将报文字符串(如十六进制)转换为字节数组,并处理长度计算。 - **设置定时器周期**:定义循环间隔(单位为毫秒),例如$T = 1000$(1秒),对应发送周期。 - **启动和停止控制**:在定时器事件中发送报文,并添加错误处理确保健壮性。 - **注意事项**: - **精度优化**:对于高要求场景(如毫秒周期),可结合 `Stopwatch` 类校正时间偏移。 - **非阻塞设计**:使用异步避免UI线程卡顿,参考引用[^2]的中断接收机制来平衡发送与接收。 - **资源配置**:参考引用[^3],通过配置文件管理定时参数(如周期值),提高灵活性[^1][^2][^3]。 以下是完整代码示例(Windows Forms应用),继承引用[^1]的报文处理逻辑: ```csharp using System; using System.Timers; using System.Windows.Forms; public partial class MainForm : Form { private System.Timers.Timer _timer; // 事件驱动定时器 private int _sendInterval = 1000; // 默认发送周期(毫秒),可配置为变量 public MainForm() { InitializeComponent(); // 初始化定时器,设置周期并添加事件处理 _timer = new System.Timers.Timer(_sendInterval); _timer.Elapsed += OnTimedEvent; // 定时事件处理程序 _timer.AutoReset = true; // true表示循环发送 _timer.SynchronizingObject = this; // UI线程同步,避免跨线程错误 } // 启动发送按钮事件 private void startButton_Click(object sender, EventArgs e) { _timer.Start(); // 启动定时器 } // 停止发送按钮事件 private void stopButton_Click(object sender, EventArgs e) { _timer.Stop(); // 停止定时器 } // 定时事件处理:发送报文逻辑 private void OnTimedEvent(object sender, ElapsedEventArgs e) { try { // 参考引用[^1],构建报文字节数组 string messageText = "000100000006010300000003"; // 示例报文 byte[] data = new byte[1024]; for (int i = 0; i < (messageText.Length - messageText.Length % 2) / 2; i++) { data[i] = Convert.ToByte(messageText.Substring(i * 2, 2), 16); } int length = data[5]; // 获取报文长度,如引用[^1] byte[] datashow = new byte[length + 6]; Array.Copy(data, datashow, length + 6); // 发送报文到服务器,参考引用[^1]的发送方法 newclient.Send(datashow); // 假设 newclient 是已初始化的网络客户端 } catch (Exception ex) { MessageBox.Show($"发送失败: {ex.Message}"); } } } ``` ### 2. **关键优化建议** - **提高定时精度**:使用 `Stopwatch` 校正计时。例如,在定时事件开始时记录时间,检查实际间隔,计算误差$\Delta t$并动态调整周期: ```csharp private Stopwatch _stopwatch = new Stopwatch(); private void OnTimedEvent(object sender, ElapsedEventArgs e) { _stopwatch.Restart(); // 重新开始计时 // ... 发送逻辑 ... long elapsedMs = _stopwatch.ElapsedMilliseconds; int adjustedInterval = Math.Max(10, _sendInterval - (int)elapsedMs); // 动态调整间隔 _timer.Interval = adjustedInterval; } ``` 这确保平均周期稳定在$T$毫秒,避免累计漂移[^2][^3]。 - **资源管理与稳健性**: - 添加`try-catch`处理发送异常,并实现重试机制(如指数退避算法)。 - 参考引用[^3],将周期值存入配置文件(App.config),支持运行时修改: ```xml <appSettings> <add key="SendInterval" value="1000" /> </appSettings> ``` 在代码中使用`ConfigurationManager.AppSettings["SendInterval"]`获取值。 - **性能考量**:在高频发送场景下(如周期$< 100$ ms),优先用 `System.Threading.Timer`,结合线程池提升效率: ```csharp private Threading.Timer _threadTimer; public void StartSending() { _threadTimer = new Threading.Timer(ThreadTimedEvent, null, 0, _sendInterval); } private void ThreadTimedEvent(object state) { // 报文发送代码(需线程同步) } ``` ### 3. **总结** 实现准确的循环周期发送报文,核心在于结合定时器和报文处理逻辑。 `System.Timers.Timer` 简单易用且UI友好,适合多数场景;而对于高频需求, `System.Threading.Timer` 加动态精度调整更优。参考引用[^1][^2][^3]的优化点(如中断接收、配置文件管理)能显著提升系统可靠性。在您项目中,建议: - 测试不同周期下的稳定性,优化网络延迟影响。 - 继承引用[^2]的发送检测机制,添加成功/失败回执处理。 - 参考引用[^3]封装服务,支持变化发送或定时推送配置[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值