当前位置: 首页 > article >正文

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

在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.kler.cn/a/511827.html

相关文章:

  • 鸿蒙子组件根据数据,刷新item Ui的规范
  • OpenMP并行编程实例系列2 —— 并行结构
  • 【2024年华为OD机试】(C卷,100分)- 悄悄话 (Java JS PythonC/C++)
  • Rust实现内网穿透工具:从原理到实现
  • 安全测评主要标准
  • 【机器学习实战中阶】音乐流派分类-自动化分类不同音乐风格
  • Ubuntu 22.04 能识别笔记本的键盘,但是无法识别外接键盘
  • 【无界】微前端技术应用
  • 【大数据】机器学习----------降维与度量学习
  • 【自动驾驶BEV感知之tesla发展历程】
  • git命令手册
  • Ubuntu 24.04 LTS 更改软件源
  • 故障诊断 | BWO白鲸算法优化KELM故障诊断(Matlab)
  • ARP 表、MAC 表、路由表、跨网段 ARP
  • (二)afsim第三方库编译(qt编译)
  • K8S 集群搭建和访问 Kubernetes 仪表板(Dashboard)
  • Java高频面试之SE-15
  • DenseNet-密集连接卷积网络
  • 服务器硬盘RAID速度分析
  • 【算法】集合List和队列
  • 第二十四课 Vue中子组件调用父组件数据
  • 从 Spark 到 StarRocks:实现58同城湖仓一体架构的高效转型
  • 算法日记4:796. 子矩阵的和(二维前缀和)
  • 前端炫酷动画--图片(一)
  • 2024年博客之星主题创作|猫头虎分享AI技术洞察:2025年AI发展趋势前瞻与展望
  • 火狐浏览器Firefox一些配置