我在VB.NET 4.8.1中工作 我创建了一个函数InvokeIfNecessary(Action),该函数判断它是否在UI线程上运行,如果没有,则调用主窗体.
Public Sub InvokeIfNecessary(act As Action)
If IsUIThread() Then
act()
Else
Application.OpenForms(0).Invoke(act)
End If
End Sub
因为它运行得非常好,所以我已经开始用这个简单的函数替换我那一团糟的.InvokeRequired和其他判断.然而,我只是收到了错误"跨线程操作无效:控件‘PB_ItemImage’从创建它的线程以外的线程访问."
在下面的代码中,on_img.Visible=False失败.我之前暂停了执行,以确认它正在UI线程中运行.该变量引用了我在设计器中创建的PictureBox,因此它显然也应该在UI线程中.(我还确认函数not位于UI线程上,因此它正在使用Invoke函数.)
Public Function ImgDisplayFromFile(ByRef img As PictureBox, imgFileName As String, Optional safe As Boolean = False)
Dim _img = img
If Not _img.IsDisposed Then InvokeIfNecessary(Sub()
MsgBox(IsUIThread()) 'This confirmed True
MsgBox(_img.InvokeRequired()) 'This is also true??
_img.Visible = False
DoOtherStuff()
End Sub)
End Function
这在其他地方一直奏效.导致此错误的原因可能有哪些不同?有什么理由不能在OpenForms(0)上调用吗?为什么调用函数中的_img.InvokeRequired会为True?
这是作为Form.Load事件的一部分在下载图像文件的任务中执行的.
艾德若要添加IsUIThread(),以判断是否需要在假设所有UI控件都在同一线程上的情况下调用主窗体:
Public Function IsUIThread() As Boolean
If Application.OpenForms.Count = 0 Then Return Nothing
Return Not Application.OpenForms(0).InvokeRequired
End Function