VB.NET无效的跨线程访问

时间:2014-05-11 02:24:13

标签: vb.net multithreading backgroundworker

我在表单上有一个后台工作者控件。

在这种形式中,我有另一种显示进展的表格:

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()"。

有人可以告诉我我做错了吗?

谢谢!

2 个答案:

答案 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,那么RunWorkerCompletedProgressChanged也将在一个单独的线程上调用,您必须如上所述在步骤1中编组对UI的调用

答案 1 :(得分:0)

在简单程序中,您可以通过将其添加到Form.Load方法来忽略跨线程错误:

CheckForIllegalCrossThreadCalls = False

请注意,在运行访问共享数据的多个异步线程时,它可能会导致问题,因此请不要随意使用它。


如果多个线程导致共享例程运行,请使用SyncLock来防止多个同时发生的实例。