正如我的标题暗示我有以下问题,我从串口接收数据,并使用control.invoke方法更新MDI表单中的richtextbox
(SerialPort.DataReceived事件中的代码)
If myTerminal.Visible Then
myTerminal.MyRichTextBox1.Invoke(New MethodInvoker(Sub()
myTerminal.MyRichTextBox1.AppendText(dataLine & vbCrLf)
End Sub))
End If
但作为mdi形式,它具有关闭和重新打开的能力。因此,当serialport将数据发送到richtextbox并且用户单击关闭按钮并且表单被释放。然后,在创建窗口句柄之前,无法在控件上调用错误“Invoke或BeginInvoke”。...任何想法????
我的问候, Ribben
答案 0 :(得分:0)
该代码不在SerialPort.DataReceived
事件中,而是在事件处理程序中。 (是的,我正在挑剔,但它指的是一个解决方案。)最好的办法是拥有myTerminal
的表单在创建时添加处理程序,并在处理程序关闭时删除处理程序。
答案 1 :(得分:0)
感谢您的回答,但不幸的是,这不是解决方案。首先,我的SerialPort类必须通知2个表单(带有richtextbox的表单,带有Listview的表单)和另一个负责绘图的类(Unmanaged Directx 9.0c约4个表单),所以为了实现我已经创建了自己的事件的serialport类。再次问题,它导致因为每次发生时Serialport.DataReceived在线程池中创建一个线程,当我处理表单时,它只是太慢而无法赶上所有线程,所以至少有一个线程调用控件已经处理好了!
作为我提出的临时解决方案(下面的代码在继承Form的TerminalForm类中):
Private VisibleBoolean As Boolean = False
Private Index As Integer = 0
Private Sub DataToAppend(ByVal _text As String)
If VisibleBoolean Then
Me.MyRichTextBox1.Invoke(New MethodInvoker(Sub()
Me.MyRichTextBox1.AppendText(_text & vbCrLf)
End Sub))
ElseIf Index = 1 Then
Index = 0
myDispose()
RemoveHandler myserialport.DataToSend2, AddressOf DataToAppend
End If
End Sub
Private Sub Me_Activated(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Activated
VisibleBoolean = True
AddHandler myserialport.DataToSend2, AddressOf DataToAppend
End Sub
Private Sub myDispose()
If Index = 0 And Not Me.IsDisposed Then
Me.Invoke(New MethodInvoker(Sub()
MyBase.Dispose(True)
End Sub))
End If
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
End Sub
Protected Overrides Sub OnFormClosing(ByVal e As System.Windows.Forms.FormClosingEventArgs)
Index = 1
VisibleBoolean = False
End Sub
我知道我也不喜欢,但至少它正在发挥作用! 任何其他改进或建议更多