串行监视器、DataReceived处理程序误解C#、WPF

0yycz8jy  于 2023-01-18  发布在  C#
关注(0)|答案(2)|浏览(243)

我正在用WPF为我的应用程序开发一个串行监视器,用C#编程。我在管理DataReceived事件时遇到了麻烦,因为我需要一个像HyperTerminal或TeraTerm这样的真实的监视器(我不使用它们,因为我希望我的终端成为以太网通信工具的一部分,我已经使用winPcap开发了这个工具)。
我必须从我的微控制器中读取一些数据,将其显示在文本框上(它只打印菜单和可用命令列表),当它完成加载序列时,我想与它交互,没有什么特别的,只是发送一个“flash-”命令来编程板的fpga。
当我尝试用接收到的数据更新textbox.text时,我的应用程序出现异常。我尝试到处搜索,但尽管有很多例子,我还是没有找到正确解释代码的东西。
这里是代码,提前感谢

namespace WpfApplication1 {
    /// <summary>
    /// Interaction logic for SerialMonitor.xaml
    /// </summary>
    public partial class SerialMonitor : Window {
        
        //VARIABLES
        public SerialPort comPort = new SerialPort();

        public SerialMonitor() {
            //initialization
            InitializeComponent();
            scanPorts();
           
        }

        
        
        private void scanPorts() {
            textBoxIndata.Clear();
            string[] ports = SerialPort.GetPortNames();
            foreach (string port in ports) {
                comboBoxPorts.Items.Add(port);
            }
        }
              
      

        private void openComBtn_Click(object sender , RoutedEventArgs e) {

            comPort.Parity = Parity.None;
            comPort.DataBits = 8;
            comPort.ReadTimeout = 500;
            comPort.StopBits = StopBits.One;

            if (comboBoxPorts.SelectedItem != null && comboBoxPorts.SelectedItem != null) {

                comPort.PortName = comboBoxPorts.SelectedItem.ToString();
                comPort.BaudRate = Convert.ToInt32(comboBoxBaud.Text);

                try {
                    //Open port and add the event handler on datareceived
                    comPort.Open();                 
                    comPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                }
                catch (Exception ex) {
                    MessageBox.Show(ex.ToString());                    
                }              
            }
            if (comPort.IsOpen) {
                label1.Content = "COM PORT OPEN";              
            }
        }

        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
            
        }

        //function to update the textBox, didn't manage to get it working
        private void updateUI (string s) {

        }


        //CLOSE AND EXIT BUTTONS
        private void closeComBtn_Click(object sender , RoutedEventArgs e) {
            if (comPort.IsOpen) {
                comPort.Close();
                label1.Content = "COM PORT CLOSED";
            }
        }

        private void exitBtn_Click(object sender , RoutedEventArgs e) {
            if (comPort.IsOpen) {
                comPort.Close();
            }
            this.Close();
        }
    }
}

我现在的问题是,当我发送我的命令使用SerialPort.Write(字符串cmd),我不能读回答案...
编辑:修正了一切,我将张贴的代码,如果有人有兴趣在编程这样一个工具

mzsu5hc0

mzsu5hc01#

DataReceived事件在另一个/次要线程上返回,这意味着您必须封送回UI线程以更新TextBox
SerialPort.DataReceived Event
从SerialPort对象接收数据时,辅助线程上会引发DataReceived事件。由于此事件是在辅助线程上引发的,而不是在主线程上引发的,因此尝试修改主线程中的某些元素(如UI元素)可能会引发线程异常。如果需要修改主窗体或控件中的元素,请使用Invoke回发更改请求。其将在适当的线程上工作。
可以使用Dispatcher.BeginInvokeDispatcher.Invoke Method封送回主线程

示例

Application.Current.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));

someControl.Dispatcher.Invoke(new Action(() => { /* Your code here */ }));
2g32fytz

2g32fytz2#

我现在的问题是,当我发送我的命令使用SerialPort.Write(字符串cmd),我不能读回答案...

相关问题