我假设您有某种 GUI 想要在刷卡时更新。我假设您有一个表单,其中包含一个名为“textBox1”的文本框和一个标记为“开始”的按钮 (button1)。
using System;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
namespace SerialPortExample {
public partial class Form1 : Form {
SerialPort myport;
public Form1() {
InitializeComponent();
myport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
myport.DataReceived += new SerialDataReceivedEventHandler(myport_DataReceived);
myport.ErrorReceived += new SerialErrorReceivedEventHandler(myport_ErrorReceived);
}
delegate void SerialDataReceivedDelegate(object sender, SerialDataReceivedEventArgs e);
delegate void SerialErrorReceivedDelegate(object sender, SerialErrorReceivedEventArgs e);
void myport_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) {
if (this.InvokeRequired) {
this.Invoke(new SerialErrorReceivedDelegate(myport_ErrorReceived_Client), sender, e);
} else {
myport_ErrorReceived_Client(sender, e);
}
}
void myport_ErrorReceived_Client(object sender, SerialErrorReceivedEventArgs e) {
MessageBox.Show("Error recieved: " + e.EventType);
}
void myport_DataReceived(object sender, SerialDataReceivedEventArgs e) {
if (this.InvokeRequired) {
this.Invoke(new SerialDataReceivedDelegate(myport_DataRecieved_Client), sender, e);
} else {
myport_DataRecieved_Client(sender, e);
}
}
void myport_DataRecieved_Client(object sender, SerialDataReceivedEventArgs e) {
textBox1.Text = myport.ReadExisting();
}
private void button1_Click(object sender, EventArgs e) {
try {
if (myport.IsOpen) {
myport.Close();
button1.Text = "Start";
} else {
myport.Open();
button1.Text = "Stop";
}
} catch (IOException ex) {
MessageBox.Show(ex.Message);
}
}
}
}
我没有串行设备来测试此代码,但它应该是正确的。
分解它,重要的部分是方法myport_DataRecieved。只要数据到达串口,即刷卡时,就会调用该方法。
其他感兴趣的领域是 Form1 构造函数,我们在其中初始化 SerialPort(但尚未打开它),以及方法 button1_Click 用于打开/关闭端口(并更改按钮的文本以反映这一点. 我们也会处理异常,以防由于某种原因无法打开端口。
编辑:感谢汉斯的评论,我已经更新了答案。您不能直接从数据事件访问 UI 控件,因为它们在不同的线程上运行。我将事件方法分成两半,这样我就可以对它们调用Invoke,并在适当的上下文中运行它们。