eat*_*mup 4 c# multithreading serial-port event-handling visual-studio-2010
我的程序的一部分使用事件处理程序来接收我的串行端口的数据.这个想法是当收到数据时,接收到的文本然后被添加到文本框(rx).我不习惯这个问题,但有些事情发生了变化,我无法弄清楚是什么.所以现在我正在重新审视这个问题的处理方式.
在winform形式加载期间,我做的最后一件事就是
if (!serialPort1.IsOpen)
{
serialPort1.Open();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
Run Code Online (Sandbox Code Playgroud)
然后我有事件处理程序
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
string indata1 = serialPort1.ReadExisting();
// rx.Text = " "; accidentally posted this. it was from trial and error.
rx.AppendText(Environment.NewLine + indata1);
}
Run Code Online (Sandbox Code Playgroud)
当我运行程序时它停在那里rx.AppendText(Environment.NewLine + indata1);
并给出错误
invalidoperationexception未处理:控制"从创建它的线程以外的线程访问.
从我能够阅读的建议我需要使用invoke
或BeginInvoke
.
我之前没有遇到任何问题,所以现在我无法理解为什么这是一个问题.从我一直在阅读的调用我只是不明白它.
有人可以帮我理解如何在我的情况下使用调用实例吗?或者可能告诉我另一种附加文本框的方法?
GUI应用程序中的更新应仅在GUI线程上完成.尝试直接更新GUI组件的另一个线程将导致您描述的错误或看似随机的行为.
Invoke
&friends 的作用是使辅助线程能够安全地将GUI更新转发到GUI线程,然后GUI线程将从队列中处理它们.
在你的情况下(假设WinForms在这里):
rx.BeginInvoke(
(Action)(() =>
{
rx.AppendText(Environment.NewLine + indata1);
}));
Run Code Online (Sandbox Code Playgroud)
BeginInvoke
是异步的,因此调用它的线程不会等待在继续之前处理实际更新,Invoke
而是同步的.
通常,您在调试模式下运行时会看到异常,如果您在发布模式下运行应用程序,则不太可能看到异常。
但是,正如您所阅读的那样,最好使用 invoke。像这样的东西:
private delegate void RefreshTextBox();
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
//this event is raised in an event separate from UI thread,
//so InvokeRequired must be checked and Invoke called to update UI controls.
if (this.InvokeRequired) {
RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults);
Invoke(d);
} else {
RefreshTextBoxResults();
}
}
private void RefreshTextBoxResults() {
string indata1 = serialPort1.ReadExisting();
rx.Text = " ";
rx.AppendText(Environment.NewLine + indata1);
}
Run Code Online (Sandbox Code Playgroud)
第一次看到这个 invoke 东西时,几乎无法理解,但仔细看看并给它一些时间,它会有意义。承诺。:)
归档时间: |
|
查看次数: |
3491 次 |
最近记录: |