帮我写一个WPF异步线程的串口通讯
时间: 2023-05-28 16:06:05 浏览: 269
以下是一个WPF异步线程的串口通讯的示例代码:
首先,在XAML文件中添加一个文本框和两个按钮,分别用于发送和接收数据:
```xml
<Window x:Class="WpfSerialComm.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Serial Communication" Height="250" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Label Content="Port Name:" Margin="10"/>
<ComboBox x:Name="cmbPortName" Width="100" Margin="5"/>
<Button x:Name="btnConnect" Content="Connect" Click="btnConnect_Click" Margin="10"/>
<Button x:Name="btnDisconnect" Content="Disconnect" Click="btnDisconnect_Click" Margin="10" IsEnabled="False"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Label Content="Send Data:" Margin="10"/>
<TextBox x:Name="txtSendData" Width="100" Margin="5"/>
<Button x:Name="btnSend" Content="Send" Click="btnSend_Click" Margin="10" IsEnabled="False"/>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="2">
<Label Content="Received Data:" Margin="10"/>
<TextBox x:Name="txtReceivedData" Width="350" Height="150" Margin="10" TextWrapping="Wrap" IsReadOnly="True"/>
</StackPanel>
</Grid>
</Window>
```
然后,在C#代码中添加以下内容:
```csharp
using System.IO.Ports;
using System.Threading.Tasks;
using System.Windows;
namespace WpfSerialComm
{
public partial class MainWindow : Window
{
private SerialPort serialPort;
public MainWindow()
{
InitializeComponent();
// 初始化串口
serialPort = new SerialPort();
serialPort.BaudRate = 9600;
serialPort.Parity = Parity.None;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Handshake = Handshake.None;
// 获取可用串口列表
string[] portNames = SerialPort.GetPortNames();
foreach (string portName in portNames)
{
cmbPortName.Items.Add(portName);
}
}
private async void btnConnect_Click(object sender, RoutedEventArgs e)
{
if (cmbPortName.SelectedItem == null)
{
MessageBox.Show("Please select a port name!");
return;
}
// 连接串口
serialPort.PortName = cmbPortName.SelectedItem.ToString();
try
{
serialPort.Open();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
// 启用发送按钮
btnSend.IsEnabled = true;
// 启用断开按钮
btnDisconnect.IsEnabled = true;
// 禁用连接按钮
btnConnect.IsEnabled = false;
// 开始异步读取数据
await Task.Run(() => ReadData());
}
private void btnDisconnect_Click(object sender, RoutedEventArgs e)
{
// 断开串口
serialPort.Close();
// 禁用发送按钮
btnSend.IsEnabled = false;
// 禁用断开按钮
btnDisconnect.IsEnabled = false;
// 启用连接按钮
btnConnect.IsEnabled = true;
}
private void btnSend_Click(object sender, RoutedEventArgs e)
{
// 发送数据
string sendData = txtSendData.Text;
serialPort.Write(sendData);
// 清空发送数据文本框
txtSendData.Text = "";
}
private void ReadData()
{
while (serialPort.IsOpen)
{
try
{
// 读取数据
string receivedData = serialPort.ReadLine();
// 在UI线程中更新文本框
Dispatcher.Invoke(() =>
{
txtReceivedData.AppendText(receivedData);
txtReceivedData.ScrollToEnd();
});
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}
```
在上面的代码中,我们首先在构造函数中初始化了串口,并获取了可用串口列表,将其添加到ComboBox控件中。在连接按钮的Click事件处理程序中,我们首先检查是否选择了串口名称,然后打开串口,启用发送和断开按钮,禁用连接按钮,并开始异步读取数据。在断开按钮的Click事件处理程序中,我们关闭串口,禁用发送和断开按钮,启用连接按钮。在发送按钮的Click事件处理程序中,我们从发送数据的文本框中获取要发送的数据,向串口写入数据,然后清空发送数据的文本框。在ReadData方法中,我们使用while循环不断读取串口接收缓冲区中的数据,然后在UI线程中更新接收数据的文本框。
注意,我们使用了异步线程来读取数据,这样可以避免在UI线程中阻塞导致界面卡顿。同时,我们使用了Dispatcher.Invoke方法来在UI线程中更新文本框,这样可以避免在异步线程中更新UI导致的线程安全问题。
在使用时,我们需要先选择串口名称,然后点击连接按钮连接串口。连接成功后,发送和断开按钮将启用,可以向串口发送数据或断开串口。接收到的数据将自动显示在接收数据的文本框中。
阅读全文