I'm working in VB.NET 4.8.1 I created a function InvokeIfNecessary(action) which checks if it's running on the UI thread and invokes to the main form if not.
Public Sub InvokeIfNecessary(act As Action)
If IsUIThread() Then
act()
Else
Application.OpenForms(0).Invoke(act)
End If
End Sub
Because it's worked really well, I've started replacing my mess of .InvokeRequired and other checks with this simple function. However I just got the error "Cross-thread operation not valid: Control 'PB_ItemImage' accessed from a thread other than the thread it was created on."
It's failing in the code below on _img.Visible=false. I've paused execution right before to confirm it was running in the UI thread. The variable refers to a PictureBox which I created in the designer, so it should also be in the UI thread, obviously. (I also confirmed that the function had not been on the UI Thread, and so it is using the Invoke function.)
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
This has been working elsewhere. What could be different to cause this error? Is there some reason why I shouldn't invoke on OpenForms(0)? Why would _img.InvokeRequired be true inside an Invoke function?
This is executing as part of a Form.Load event, inside a Task that is downloading the image file.
Ed. to add IsUIThread() which checks if the main form requires invoking under the assumption that all UI controls are on the same thread:
Public Function IsUIThread() As Boolean
If Application.OpenForms.Count = 0 Then Return Nothing
Return Not Application.OpenForms(0).InvokeRequired
End Function