Sha*_*dra 2 vb.net multithreading event-handling
如何使用另一个类的线程正在接收的消息更新 GUI 中的数据?
我有一个带有从服务器接收数据的线程的类。每当从服务器获取消息时,该线程就会引发一个事件。此事件在 Starter Class(包含 GUI 的主类)内处理。事件处理程序(比如说DisplayData() 必须显示其他类收到的消息。我的代码是这样的
Class GUI
receiverObj = New Receiver()
Addhandler receiverObj.MessageAlert, Addressof DisplayData
...
...
Sub DisplayData()
Dim str As receiverObj.ReceiveData
lbEvents.Add.Items(str) ' lbEvents is a ListBox inside the GUI that displays messages from Receiver
End Sub
End Class
Class Receiver
Public Event MessageAlert()
Sub New ()
MyTcpClient = New TcpClient(hostIP, port)
MyTcpClient.GetStream.BeginRead(ReceiveData, 0, PacketSize, AddressOf ReceiveStream, Nothing)
End Sub
Public Sub ReceiveStream(ByVal ar As IAsyncResult)
Dim ByteCount As Integer
Try
ByteCount = MyTcpClient.GetStream.EndRead(ar)
Dim t As New Threading.Thread(Sub() RaiseEvent MessageAlert())
MyTcpClient.GetStream.BeginRead(ReceiveData, 0, PacketSize, AddressOf ReceiveStream, Nothing)
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
窗口崩溃或挂起,列表框不显示数据。抛出异常说
跨线程操作无效:控制 xxx 从创建它的线程以外的线程访问。
任何人都可以提出解决此错误的方法吗?如何使用另一个类的线程正在接收的消息更新 GUI 中的数据?
Windows 应用程序的 GUI 元素的更新必须在创建 GUI 的线程上进行。
为了解决这个问题,有一个名为 Invoke 的方法,它允许您触发一个委托,该委托可以确保将控制权传递给 GUI 线程并执行您正在尝试的更新。
你需要做一些事情来完成这项工作:
甲委托类型,如
Delegate Sub MyGUIUpdateDelegate()Run Code Online (Sandbox Code Playgroud)委托类型的变量
Public myGUIUpdateDelegate as MyGUIUpdateDelegateRun Code Online (Sandbox Code Playgroud)具有与委托匹配并完成工作的签名的方法:
Public Sub MyGuiEventHandler()
' Do work on proper GUI thread, via Control.Invoke, ' such as listbox population
If (Me.InvokeRequired) Then Me.Invoke( myGUIUpdateDelegate) Else // do control specific work, we're on the GUI thread here End If
End Sub
将事件处理程序分配给您的委托:
myGUIUpdateDelegate = New MyGuiUpdateDelegate(AddressOf myForm.MyGuiEventHandler)通过 Control.Invoke 从事件线程调用您的更新程序方法到适当的线程(假设您的表单实例变量名为 myForm):
myForm.Invoke(myForm.myGUIUpdateDelegate);这至少是一个可以帮助您入门的框架。这个想法是想要引发更新的后台线程不应该(实际上也不能)进行直接的 GUI 更新。启动到 GUI 线程的上下文切换的正确方法是通过调用 Invoke 方法在适当的 GUI 线程上调用 GUI 更新程序。
此外,如果您需要将参数传递给您的委托,只需更改您定义的委托的签名以包含参数,并修改 Invoke 方法以在处理程序中提供参数,并将第二个参数提供给 Invoke。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
8463 次 |
| 最近记录: |