在我通过串口接收数据的处理程序中,当收到数据时,我将其存储到字符串中并执行.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处于活动状态,它会检测调制解调器的状态。
我只是看不到发生了什么。有人可以向我解释为什么会这样吗?
答案 0 :(得分:3)
但是,如果我删除了RefreshTextBoxResults()
中第一行的注释
这是关键词。问题是您使用ReadExisting()。串行端口非常慢,DataReceived事件处理程序通常只能获得一个或两个字符。通过显示消息框,您减慢速度。这允许串行端口驱动程序读取更多字符。足以让ReadExisting读取整个“已连接”字符串,而不仅仅是“C”或“Co”。
使用调试器时也难以诊断,单步执行代码也会使代码速度变慢,以使端口能够获得足够的字符。
您需要做的是在获得整个响应字符串后处理响应 。使用调制解调器总是很容易,只需使用ReadLine()而不是ReadExisting()。您可能需要调整NewLine属性的值。
答案 1 :(得分:1)
MessageBox()
启动模态对话框消息循环,这将允许排队的窗口消息有机会被处理。可以想象,您在RefreshTextboxResults()函数中对文本框控件所做的一些操作会将消息发布到控件窗口句柄。如果是这种情况,窗口句柄将不会收到此类消息,直到执行流程进入或返回到消息循环。如果你打开一个模态对话框(如MessageBox),这将在你的函数中发生。
并非这是一个解决方案,但它应该确认这一理论:尝试通过调用MessageBox()
替换Application.DoEvents()
。 (假设您的应用程序是WinForms应用程序)如果这样可以将阻塞程度调整到与调用MessageBox()
相同的程度,那么很明显您在消息队列中堆积了一些需要处理的待处理消息。
答案 2 :(得分:0)
我建议你阻止申请,直到数据完全收到,或者你可以使用后台为你完成工作。