C# 以一定间隔从串行端口读取数据?

C# 以一定间隔从串行端口读取数据?,c#,serial-port,C#,Serial Port,我有一个带串口接口的磁卡读卡器 我使用以下C#.net代码向读卡器发送命令 System.IO.Ports.SerialPort myport = new System.IO.Ports.Serialport("COM1", 9600, Parity.Nonek, 8, StopBits.One); myport.Open(); // initiates the card reader to read. myport.write("command to initiate card reader"

我有一个带串口接口的磁卡读卡器

我使用以下C#.net代码向读卡器发送命令

System.IO.Ports.SerialPort myport = new System.IO.Ports.Serialport("COM1", 9600, Parity.Nonek, 8, StopBits.One);
myport.Open();
// initiates the card reader to read.
myport.write("command to initiate card reader");

// Once the card is swiped it shows the read data.
MessageBox.Show(myport.ReadExisting());
myport.Close();
当我在Messagebox之前有一些停顿时,上面的代码将很好地工作。但我不想暂停,而是想在刷卡时启动messagebox

我们怎么能这样做呢


我在用户登录系统中实现了这一点。

我假设您有某种GUI,希望在刷卡时进行更新。我假设您有一个表单,其中有一个名为“textBox1”的文本框和一个标记为“Start”(button1)的按钮

我没有串行设备来测试这段代码,但它应该是正确的

分解它,重要的部分是方法
myport\u datareceived
。每当数据到达串行端口时,即刷卡时,就会调用此方法

其他感兴趣的领域是
Form1
构造函数,在这里我们初始化SerialPort(但还没有打开它),以及方法
按钮1\u单击
打开/关闭端口(并更改按钮的文本以反映这一点)。我们还处理异常,以防由于某种原因无法打开端口


编辑:由于Hans的评论,我已经更新了答案。您无法直接从数据事件访问UI控件,因为它们运行在不同的线程上。我将事件方法一分为二,这样我可以调用它们,并在适当的上下文中运行它们。

我假设您有某种要更新的GUI刷卡。我假设您有一个表单,其中有一个名为“textBox1”的文本框和一个标签为“Start”的按钮(button1)

我没有串行设备来测试这段代码,但它应该是正确的

分解它,重要的部分是方法
myport\u datareceived
。每当数据到达串行端口时,即刷卡时,就会调用此方法

其他感兴趣的领域是
Form1
构造函数,在这里我们初始化SerialPort(但还没有打开它),以及方法
按钮1\u单击
打开/关闭端口(并更改按钮的文本以反映这一点)。我们还处理异常,以防由于某种原因无法打开端口


编辑:由于Hans的评论,我已经更新了答案。您无法从数据事件直接访问UI控件,因为它们运行在不同的线程上。我将事件方法一分为二,以便可以调用
Invoke
,并在适当的上下文中运行它们。

代码完全错误,您无法从线程访问UI运行DataReceived事件处理程序的线程池。代码完全错误,您无法从运行DataReceived事件处理程序的线程池线程访问UI。
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);
            }
        }
    }
}