2012-01-24 16 views
0

也许我正在弯腰......但事实是,我有点线程n00b ...跨线程从类中调用?困惑 - vb.net

我正在使用类中的串行端口。我正在从这个班级向我的表格提出一个事件,称为班级。事件包含收到的数据...

我希望简单地从引发事件中填充文本框。

现在我没有专门创建一个单独的线程,但是当我尝试在UI上更新我的文本框时遇到了正常的crossthreading错误,所以我的假设是串行端口及其内部方法可能会创建它自己的线程。 。

无论如何,我有点困惑,如何正确实现的调用,从我的主要形式,指着实例化的类不知所云,

我希望这是有道理的......

Dim WithEvents tmpRS232 As New clsRS232

Private Sub but_txt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles but_txt.Click 
    tmpRS232.Set_com_port("COM8", 38400) 
    tmpRS232.Transmit_data(txt_tx.Text) 
End Sub 

Private Sub tmprs232_rx_data_returned(ByVal str_data As String) Handles tmpRS232.rx_data_returned 
    txt_rx.Text = str_data 'Cross threading error 
    MsgBox(str_data) 'Fires without errors 
End Sub 

有人可以提供基于此代码的代码示例吗?

谢谢。

+0

您不能从没有UI线程修改UI [如何更新从C#另一个线程GUI] [1] [1] :http://stackoverflow.com/questions/661561/how-to-update-gui-from-another-thread-in-c – Andrew

+0

嗯,我知道......只是不确定在这种情况下“如何”调用... –

回答

5

你是对的,这里的问题是你正试图从非UI线程(在本例中是串口处理程序)更新UI元素。你需要做的是检查你试图从回调中访问的控件是否设置了InvokeRequired标志。如果是这样,这意味着你需要编组你的调用UI线程。您可以通过使用Invoke或从System.Windows.Forms.Control的BeginInvoke实现此目的。

Private Delegate Sub SetRxTextCallback(ByVal [text] As String) 

Private Sub SetRxText(ByVal [text] As String) 
    txt_rx.Text = [text] 
End Sub 

Private Sub tmprs232_rx_data_returned(ByVal str_data As String) Handles tmpRS232.rx_data_returned 

    If (txt_rx.InvokeRequired) Then 
     Dim d As New SetRxTextCallback(AddressOf Me.SetRxText) 
     Me.BeginInvoke(d, New Object() {[str_data]}) 
    End If 

    'txt_rx.Text = str_data 'Cross threading error 
    'MsgBox(str_data) 'Fires without errors 
End Sub 

下面是MSDN文档的链接,详细解释它。

+0

多数民众赞成我正在寻找兄弟...谢谢一堆...(双关语意:-)) –

2

或者干脆...

Private Sub tmprs232_rx_data_returned(ByVal str_data As String) Handles tmpRS232.rx_data_returned 
    If InvokeRequired Then 
     Invoke(Sub()txt_rx.Text = str_data) 
    Else 
     txt_rx.Text = str_data 
    End If 
End Sub 
+0

谢谢西蒙。赞赏。 –