C#多个不同类型设备串口通讯,使用异步多线程不卡界面示例
时间: 2024-10-08 11:19:24 浏览: 34
解析C#多线程编程中异步多线程的实现及线程池的使用
在C#中,如果你需要同时处理来自不同类型的设备(如串口、蓝牙等)的数据,并且希望保持用户界面不被阻塞(即防止UI线程因为数据接收而变得卡顿),可以使用异步编程和多线程技术。以下是一个简单的示例,假设我们有一个串口设备连接:
```csharp
using System;
using System.IO.Ports;
using System.Threading.Tasks;
public partial class MainForm : Form
{
private SerialPort _serialPort1; // 代表第一个串口设备
private SerialPort _serialPort2; // 代表第二个串口设备
public MainForm()
{
InitializeComponent();
// 初始化串口对象
_serialPort1 = new SerialPort("COM1");
_serialPort2 = new SerialPort("COM2");
// 开始监听两个串口的事件,异步处理
Task.Run(ReceiveDataFromSerialPortAsync(_serialPort1));
Task.Run(ReceiveDataFromSerialPortAsync(_serialPort2));
// UI更新部分
Task.Run(() => UpdateForm());
}
async private Task ReceiveDataFromSerialPortAsync(SerialPort port)
{
try
{
port.DataReceived += Port_DataReceived;
await port.OpenAsync(); // 等待打开串口
}
catch (Exception ex)
{
Console.WriteLine($"Error opening serial port: {ex.Message}");
}
}
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string data = sp.ReadExisting(); // 读取接收到的数据
ProcessReceivedData(data); // 在新线程中处理数据,避免阻塞UI
}
private async void UpdateForm()
{
while (!IsDisposed)
{
// 更新UI操作,比如显示实时数据...
await Task.Delay(100);
}
}
// 这里只是简单地处理数据,实际应用中可能会有更复杂的解析逻辑
private void ProcessReceivedData(string receivedData)
{
Task.Run(() =>
{
// 在后台线程处理数据,例如添加到日志或数据显示控件
// ...
});
}
// 形式上关闭Form
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
// 关闭串口任务
_serialPort1.Close();
_serialPort2.Close();
IsDisposed = true;
}
}
```
在这个示例中,`ReceiveDataFromSerialPortAsync`方法启动一个新的线程去接收数据,当串口有新的数据到达时,会触发`Port_DataReceived`事件,然后在另一个线程中处理数据,从而保证了UI的流畅性。
阅读全文