1

在通过串行端口接收数据的处理程序中,当接收到数据时,我将其存储到一个字符串中并执行 .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() 时,它应该返回呼叫状态和类型(如果有)。正如我在提示框中看到的那样,调制解调器确实会响应。如果单词 connected 在那里的任何地方它应该将标签的文本更改为“Connected”。随着代码的放置,该标签没有任何反应。但是,如果我删除 RefreshTextBoxResults() 中第一行的注释,使 MessageBox 处于活动状态,它会检测调制解调器的状态。

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

4

3 回答 3

3

但是,如果我删除 RefreshTextBoxResults() 第一行的注释

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

当您使用调试器时也很难诊断,单步执行代码也会减慢它的速度,以允许端口获得足够的字符。

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

于 2012-08-29T23:50:34.670 回答
1

MessageBox() starts a modal dialog message loop, which will allow queued window messages an opportunity to be processed. It's conceivable that some of the manipulations you're doing to the textbox control in your RefreshTextboxResults() function post messages to the control window handle. If this is the case, the window handle won't receive such messages until execution flow enters or returns to the message loop. That will happen in your function if you open a modal dialog (like MessageBox).

Not that this is a solution, but it should confirm this theory: try replacing MessageBox() with a call to Application.DoEvents(). (Assuming your app is a WinForms app) If this clears up the blockage to the same degree as calling MessageBox(), then it's pretty clear that you have some pending messages piled up in the message queue that need to be dealt with.

于 2012-08-29T23:27:55.333 回答
0

我建议您阻止应用程序,直到完全收到数据,或者您可以使用后台踏板为您完成这项工作。

于 2012-08-30T17:58:45.727 回答