也许这是一个简单的问题,我只是不知道正确的搜索条件来找到答案,但我的Google-fu失败了我在这一个。从后台线程打开一个模态窗体来阻塞UI线程而不阻止后台线程
我的vb.net应用程序有一个控制所有套接字通信的后台线程。有时候,我需要这个通信线程来打开一个模态窗体来显示一条消息并阻止UI交互,直到通信线程完成一系列任务之后,通信线程将移除模态窗体,从而允许用户继续交互。
目前,我的通信类包含后台线程有两个事件,StartBlockingTask和EndBlockingTask。我的主窗体具有这些事件的事件监听器,这些事件调用了like-named subs。他们叫代码看起来像这样:
Private Delegate Sub BlockingDelegate(ByVal reason As String)
Private Sub StartBlockingTask(ByVal reason As String)
If Me.InvokeRequired Then
Dim del As New BlockingDelegate(AddressOf StartBlockingTask)
Me.Invoke(del, New Object() {reason})
Else
Try
_frmBlock.lblBlock.Text = reason
_frmBlock.ShowDialog()
Catch ex As Exception
'stuff
End Try
End If
End Sub
Private Sub EndBlockingTask()
If Me.InvokeRequired Then
Dim del As New BlockingDelegate(AddressOf EndBlockingTask)
Me.Invoke(del, New Object() {""})
Else
Try
If (Not _frmBlock Is Nothing) Then
_frmBlock.DialogResult = Windows.Forms.DialogResult.OK
End If
Catch ex As Exception
'stuff
End Try
End If
End Sub
这成功地阻止从交互用户界面,但它也能阻止通信线程,因此EndBlockingTask事件从来没有真正得到提高。如何从通信线程打开此模式对话框并允许通信线程继续运行?
在此先感谢!
我回到这里重新阅读我给出的答案,因为重新安排了一些代码后,被调用的方法开始再次阻塞线程。你的评论立即修复它。谢谢。我现在明白了Invoke和BeginInvoke之间的区别! – e2579382
这是一种大多数新的线程都不能实现的区别,因为现在的计算机如此之快,以至于Invoke()调用看起来不是异步的。您的场景就是演示其差异的最佳例子! –