在C#中添加I/O延时和持续时间

devtools/2025/1/24 5:07:14/

在C#中添加I/O延时和持续时间,可以通过以下方法实现。具体来说,延时可以通过Thread.Sleep、Task.Delay等方式来模拟延迟,而持续时间的控制可以通过循环结构来设定持续的时间。在执行I/O操作时,你可以在操作之间添加延时,从而达到你想要的效果。
方法 1:使用 Thread.Sleep 模拟延迟
如果你希望在执行I/O操作时控制每个操作之间的延时,可以使用 Thread.Sleep 来暂停线程一定时间。这种方法适用于不需要异步处理的情况。
示例:延时和持续时间控制

using System;
using System.IO.Ports;
using System.Threading;
using System.Windows;namespace WpfApp
{public partial class MainWindow : Window{private SerialPort serialPort;private bool isSendingData;private int durationInSeconds = 10; // 设置持续时间为10秒public MainWindow(){InitializeComponent();InitializeSerialPort();}// 初始化串口private void InitializeSerialPort(){serialPort = new SerialPort("COM1", 9600);  // 设置串口号和波特率serialPort.Open(); // 打开串口}// 启动I/O持续发送功能private void StartSendingData(){if (isSendingData) return;isSendingData = true;DateTime startTime = DateTime.Now; // 获取开始时间while (isSendingData && (DateTime.Now - startTime).TotalSeconds < durationInSeconds){try{// 模拟发送数据到串口string dataToSend = "Hello, World!";serialPort.WriteLine(dataToSend);Console.WriteLine("Sending: " + dataToSend);// 添加延时,控制发送的频率Thread.Sleep(1000); // 每次发送数据后延时1秒}catch (Exception ex){MessageBox.Show($"Error sending data: {ex.Message}");break; // 如果发生错误,退出循环}}StopSendingData();}// 停止I/O持续发送功能private void StopSendingData(){isSendingData = false;}// 界面按钮事件示例:开始按钮private void StartButton_Click(object sender, RoutedEventArgs e){StartSendingData();}// 界面按钮事件示例:停止按钮private void StopButton_Click(object sender, RoutedEventArgs e){StopSendingData();}// 界面关闭时,关闭串口连接private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e){StopSendingData();if (serialPort.IsOpen){serialPort.Close();}}}
}

代码解释:

1.Thread.Sleep(1000):在每次发送数据后,线程会暂停1秒(1000毫秒)。这样就可以控制数据发送的频率。
2.DateTime startTime = DateTime.Now:记录开始时间,然后通过 DateTime.Now - startTime 来计算程序运行的时间,直到超过预定的持续时间(durationInSeconds)时停止发送数据。
3.while 循环:只要未超过持续时间,并且 isSendingData 为 true,就持续发送数据。

方法 2:使用异步和 Task.Delay 来模拟延时
如果你想在不阻塞主线程的情况下执行I/O操作并添加延时,可以使用 async 和 await 配合 Task.Delay。Task.Delay 是一个异步方法,它不会阻塞线程。
示例:异步延时和持续时间控制

using System;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Windows;namespace WpfApp
{public partial class MainWindow : Window{private SerialPort serialPort;private bool isSendingData;private int durationInSeconds = 10; // 设置持续时间为10秒public MainWindow(){InitializeComponent();InitializeSerialPort();}// 初始化串口private void InitializeSerialPort(){serialPort = new SerialPort("COM1", 9600);  // 设置串口号和波特率serialPort.Open(); // 打开串口}// 启动I/O持续发送功能private async Task StartSendingDataAsync(){if (isSendingData) return;isSendingData = true;DateTime startTime = DateTime.Now; // 获取开始时间while (isSendingData && (DateTime.Now - startTime).TotalSeconds < durationInSeconds){try{// 模拟发送数据到串口string dataToSend = "Hello, World!";serialPort.WriteLine(dataToSend);Console.WriteLine("Sending: " + dataToSend);// 添加异步延时,避免阻塞UI线程await Task.Delay(1000); // 每次发送数据后延时1秒}catch (Exception ex){MessageBox.Show($"Error sending data: {ex.Message}");break; // 如果发生错误,退出循环}}StopSendingData();}// 停止I/O持续发送功能private void StopSendingData(){isSendingData = false;}// 界面按钮事件示例:开始按钮private async void StartButton_Click(object sender, RoutedEventArgs e){await StartSendingDataAsync();}// 界面按钮事件示例:停止按钮private void StopButton_Click(object sender, RoutedEventArgs e){StopSendingData();}// 界面关闭时,关闭串口连接private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e){StopSendingData();if (serialPort.IsOpen){serialPort.Close();}}}
}

代码解释:

4.Task.Delay(1000):替代了 Thread.Sleep,它是异步的,能够避免阻塞UI线程。每次发送数据后,程序会延时1秒。
5.async 和 await:通过这些关键字来确保异步执行,不会阻塞主线程。
6.通过 StartButton_Click 使用 await StartSendingDataAsync() 来启动数据发送过程。

总结:

1.延时控制:通过 Thread.Sleep 或 Task.Delay 控制每个I/O操作之间的延时。
2.Thread.Sleep 是同步的,会阻塞当前线程,但在某些情况下使用起来简单。
3.Task.Delay 是异步的,可以避免阻塞UI线程,更适合在WPF这样的UI应用中使用。
4.持续时间控制:通过记录开始时间和与当前时间进行比较来控制操作持续的时间。

根据你的需求,你可以选择适合的方法来添加延时和持续时间控制。


http://www.ppmy.cn/devtools/153049.html

相关文章

【机器学习应用】预处理与特征工程

这里是阿川的博客,祝您变得更强 ✨ 个人主页:在线OJ的阿川 💖文章专栏:机器学习应用入门到进阶 🌏代码仓库:GitHub平台 写在开头 现在您看到的是我的结论或想法,但在这背后凝结了大量的思考、经…

重学设计模式-单例模式

一、什么是单例模式 单例模式,从字面意思理解,就是保证一个类只有一个实例,并提供一个全局访问点来访问这个实例。想象一下,在一个大型游戏中,游戏的配置信息类,整个游戏运行期间只需要一份配置数据就够了…

如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?

这里,我们以比较知名的商业新知网站https://www.shangyexinzhi.com/为例进行代码编写,下面进行代码应用思路。 第一部分,分析网站结构 首先,我们来分析,要使用Python技术分析一个网站的结构,通常可以通过…

使用 JMeter 的 Autostop Listener 插件:自动化性能测试的守护者

在性能测试中,监控测试执行的状态并及时做出响应是至关重要的。如果测试过程中出现性能瓶颈或系统崩溃,继续运行测试可能会导致资源浪费或测试结果不准确。JMeter 的 Autostop Listener 插件正是为了解决这一问题而设计的。它允许你设置自动化停止条件&a…

【Ubuntu】安装SSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端: sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端: sudo systemctl start ssh贰、配置SSH(可跳过) 配置文件 …

两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 思路 这道题目正常模拟就行了。//我还不熟练如何模拟,我在这方面还是差了点,毕竟还算是新手。所有链表都建议使用虚拟头结点。 ListNode *swap(ListNode *head) {Lis…

【vitePress】基于github快速添加评论功能(giscus)

一.添加评论插件 使用giscus来做vitepress 的评论模块,使用也非常的简单,具体可以参考:giscus 文档,首先安装giscus npm i giscus/vue 二.giscus操作 打开giscus 文档,如下图所示,填入你的 github 用户…

C# 委托和事件(事件)

回调(callback)函数是Windows编程的一个重要部分。C或C编程背景,在许多Windows API中使用过回调。VB添加AddressOf关键字后,开发人员就可以利用以前一度受到限制的API。回调函数实际上是方法调用的指针也称为函数指针。.NET以委托的形式实现函…