我在表单上有一个后台工作者控件。
在这种形式中,我有另一种显示进展的表格:
Private _fWait As frmWait
我正在更新此表单,更改其标签以告知用户当前正在进行的操作。
当后台工作者完成后,我想关闭此表单_fWait。
我正在使用
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
'do the background worker stuff. I have not stated it here because it is not important
_fWait.Close()
_bDone = True
End Sub
但是我收到错误"无效的跨线程访问:对控件frmWait的访问是从一个不同的线程发生的,而不是它创建的线程。"在线" _fWait.Close()"。
有人可以告诉我我做错了吗?
谢谢!
答案 0 :(得分:1)
当您调用_fWait.Close()
时必须在UI线程上调用,而BackgroundWorker1_DoWork
处理程序将在另一个线程上运行,这就是您收到错误的原因。关闭表单有两种选择:
1)继续关闭DoWork
处理程序上的表单,但使用类似下面的代码将请求编组到UI线程上:
this.Invoke(() => _fWait.Close());
自从我完成VB以来已经有一段时间了,所以你必须将C#代码转换为VB ...抱歉。
2)处理RunWorkerCompleted
事件并将其关闭。如果您启动了BackgroundWorker
在UI线程中,也会在UI线程上调用RunWorkerCompleted
。
如果我没记错的话,假设在UI线程上创建ProgressedChanged
,也会在UI上调用BackgroundWorker
事件。如果另一个线程创建了BackgroundWorker
,那么RunWorkerCompleted
和ProgressChanged
也将在一个单独的线程上调用,您必须如上所述在步骤1中编组对UI的调用
答案 1 :(得分:0)
在简单程序中,您可以通过将其添加到Form.Load方法来忽略跨线程错误:
CheckForIllegalCrossThreadCalls = False
请注意,在运行访问共享数据的多个异步线程时,它可能会导致问题,因此请不要随意使用它。
如果多个线程导致共享例程运行,请使用SyncLock来防止多个同时发生的实例。