【问题标题】:Serial monitor, DataReceived handler misunderstanding C#, WPF串行监视器、DataReceived 处理程序误解 C#、WPF
【发布时间】:2018-05-31 08:23:57
【问题描述】:

我正在为我的 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(string cmd) 发送命令时,我无法回读答案...

编辑:修复了所有问题,如果有人对编写这样的工具感兴趣,我将发布代码:)

【问题讨论】:

  • 你得到了什么异常?
  • 这是 DataReceivedHandler private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { string inData = comPort.ReadExisting(); textBoxIndata.AppendText(inData); } 但它给了我一个线程冲突
  • "调用线程无法访问该对象,因为另一个线程拥有它。"

标签: c# wpf serial-port serial-communication


【解决方案1】:

DataReceived 事件在另一个/辅助线程上返回,这意味着您必须编组回 UI 线程来更新您的 TextBox

SerialPort.DataReceived Event

数据接收时在辅助线程上引发 DataReceived 事件 从 SerialPort 对象接收。因为这个事件是在一个 辅助线程,而不是主线程,试图修改一些 主线程中的元素,例如 UI 元素,可能会引发 线程异常。如果需要修改 main 中的元素 表单或控件,使用 Invoke 将更改请求发布回来,这样就可以了 在正确的线程上工作。

您可以使用Dispatcher.BeginInvokeDispatcher.Invoke Method 来封送回主线程

示例

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

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

【讨论】:

    【解决方案2】:

    我现在遇到的问题是,当我使用 SerialPort.Write(string cmd) 发送命令时,我无法回读答案...

    【讨论】:

    • 你能显示代码吗?我在给出的示例中没有看到 Write 命令。
    • 你使用SerialPort.Write命令后,至少要等到收到响应吗?
    • 解决了这个问题,我必须正确设置端口,如果有人对与此非常相似的工具感兴趣,我会发布代码:)
    • 我有兴趣查看您的解决方案,但更重要的是,我认为这对在搜索中找到此主题并想知道答案的其他人有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多