正如我的标题所暗示的那样,我有以下问题,我从串行端口接收数据,并且我用control.invoke方法更新MDI表单中的richtextbox
(串行端口中的代码。数据接收事件)
If myTerminal.Visible Then
myTerminal.MyRichTextBox1.Invoke(New MethodInvoker(Sub()
myTerminal.MyRichTextBox1.AppendText(dataLine & vbCrLf)
End Sub))
End If
但作为一个mdi形式,它有能力关闭和重新打开。因此,当串行端口将数据发送到richtextbox时,用户单击关闭按钮,表单就会被处理掉。然后出现错误"在创建窗口句柄之前,不能对控件调用Invoke或BeginInvoke。"…有什么想法吗????
我的问候,Ribben
该代码不在SerialPort.DataReceived
事件中,而是在的事件处理程序。(是的,我很挑剔,但它指向了一个解决方案。)最好的做法是让拥有myTerminal
的表单在创建时添加处理程序,在关闭时删除处理程序。
感谢您的回答,但不幸的是,这不是解决方案。首先,我的SerialPort类必须通知2个Forms(Form with richtextbox,Form with Listview)和另一个负责绘图的类(Unmanaged Directx 9.0c about 4 Forms),所以为了正确实现串行端口类,我制作了自己的事件。再次谈到问题,这是因为每次收到的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
我知道我两个都不喜欢,但至少它起作用了!任何其他改进或建议都更具