串行数据仅适用于messagebox

时间:2012-08-29 23:00:46

标签: c# visual-studio-2010 serial-port

在我通过串口接收数据的处理程序中,当收到数据时,我将其存储到字符串中并执行.contains搜索以确定是否需要对数据执行某些操作。当应用程序处于空闲状态时(让我们称之为调制解调器)发送类似“已连接”的内容,它可以正常工作。

问题是当我轮询机器时。当我发起一个期望返回结果的命令时,它不起作用,我无法找出原因。现在,如果我使用消息框启动该功能,它将起作用。我宁愿没有不必要的消息框。

以下是我的代码示例。

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    if (this.InvokeRequired)
    {
        RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
        Invoke(d);
    }
    else
    {
        RefreshTextBoxResults();
    }
}

private void RefreshTextBoxResults()
{
    //MessageBox.Show("refresh text is occurring");
    indata1 = serialPort1.ReadExisting();
    rx.AppendText(indata1);

    string dataCheck = indata1.ToUpper();

    //MessageBox.Show(dataCheck);
    if (indata1.ToUpper().Contains("CONNECT"))//dataCheck.Contains("CONNECT"))
    {
        // MessageBox.Show("connect");
        cState.Text = "Connected";
        if(connected==false)
            connectLink();
    }
    if (dataCheck.Contains("CONNECTED"))
    {
        // MessageBox.Show("Active Call in Session");
        cState.Text = "Connected";
        if (connected==false)
            connectLink();
    }
    if (dataCheck.Contains("NO"))
    {
        cState.Text = "Disconnected";
        disconnect();
    }
    if (dataCheck.Contains("CAMPOS"))
    {
        campos = indata1;
        camDat = true;
    }
}

private void cState_Click(object sender, EventArgs e)
{
    writeDevice("callstatus");
}

public void writeDevice(string cmd)
{
    try
    {
        {
            serialPort1.Write(cmd + "\r\n");
        }
    }
    catch
    { noconnect(); }
}

当我执行cstate()时,它应该返回呼叫状态并输入(如果有的话)。调制解调器确实响应,因为我可以在提示框中看到它。如果连接的单词在那里的任何地方它应该将标签的文本更改为“已连接”。代码所在,该标签没有任何反应。但是,如果我删除了RefreshTextBoxResults()中第一行的注释,使MessageBox处于活动状态,它会检测调制解调器的状态。

我只是看不到发生了什么。有人可以向我解释为什么会这样吗?

3 个答案:

答案 0 :(得分:3)

  

但是,如果我删除了RefreshTextBoxResults()

中第一行的注释

这是关键词。问题是您使用ReadExisting()。串行端口非常慢,DataReceived事件处理程序通常只能获得一个或两个字符。通过显示消息框,您减慢速度。这允许串行端口驱动程序读取更多字符。足以让ReadExisting读取整个​​“已连接”字符串,而不仅仅是“C”或“Co”。

使用调试器时也难以诊断,单步执行代码也会使代码速度变慢,以使端口能够获得足够的字符。

您需要做的是在获得整个响应字符串后处理响应 。使用调制解调器总是很容易,只需使用ReadLine()而不是ReadExisting()。您可能需要调整NewLine属性的值。

答案 1 :(得分:1)

MessageBox()启动模态对话框消息循环,这将允许排队的窗口消息有机会被处理。可以想象,您在RefreshTextboxResults()函数中对文本框控件所做的一些操作会将消息发布到控件窗口句柄。如果是这种情况,窗口句柄将不会收到此类消息,直到执行流程进入或返回到消息循环。如果你打开一个模态对话框(如MessageBox),这将在你的函数中发生。

并非这是一个解决方案,但它应该确认这一理论:尝试通过调用MessageBox()替换Application.DoEvents()。 (假设您的应用程序是WinForms应用程序)如果这样可以将阻塞程度调整到与调用MessageBox()相同的程度,那么很明显您在消息队列中堆积了一些需要处理的待处理消息。

答案 2 :(得分:0)

我建议你阻止申请,直到数据完全收到,或者你可以使用后台为你完成工作。