System.InvalidOperationException: Cross-thread operation not valid
All,
I have a main VB form (frmMain). frmMain has-a subForm (frmOPC), and declares a private member of type frmOPC WithEvents.
VB Code:
' frmMain
Option Explicit
' ...
' This is my SubForm which can Raise an Event
Private WithEvents m_frmOPC as frmOPC
I wish frmMain to respond graphically to an Event Raised by frmOPC, such as update a frmMain.Label.Text = "something" when frmMain captures an Event Raised by its subForm, frmOPC.
VB Code:
Private Sub m_frmOPC_OPC_DataWriteVerified(ByVal intLaneNum As Integer) Handles m_frmOPC.OPC_DataWriteVerified
The SubForm has-a VB6-developed ActiveX control which Raises an Event.
VB Code:
' frmOPC
Option Explicit
Imports ActiveX_Library
' ...
' This is my ActiveX Object which can Raise an Event
Private WithEvents m_OPC_Process As ActiveX_Library.OPC_Process.cls_OPC_Group
Obviously, when the VB6 ActiveX Object Raises an Event, I capture this Event, and in turn, Raise my own Event:
VB Code:
Private Sub m_OPC_Process_DataChanged(ByRef Context As String, ByRef TagName As String, ByRef TagValue As String) Handles m_OPC_Process.DataChanged
RaiseEvent OPC_DataWriteVerified(m_intLaneNum)
' Notice, the frmMain is trying to update it's screen right now I think, before this Event has finished...
End Sub
The problem? I'm glad you asked! frmMain will puke a hard-to-track-down error if I try to mutate an object on the Form:
Code:
System.InvalidOperationException: Cross-thread operation not valid: Control 'lblOPC_Result' accessed from a thread other than the thread it was created on.
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.set_WindowText(String value)
at System.Windows.Forms.Control.set_Text(String value)
at System.Windows.Forms.Label.set_Text(String value)
at RUUD_Production_Supervisor.frmMain.m_frmOPC_OPC_DataWriteVerified(Int32 intLaneNum) in E:\Work\Visual Studio 2005\Projects\RUUD_Production_Supervisor\RUUD_Production_Supervisor\frmMain.vb:line 188
Interestingly, I can do anything non-graphical with no issues. The error is only thrown when I try to make changes to the Form's screen Objects.
I found a workaround, which is always green squiggled as a warning in the IDE at design-time, but effectively removes the erroneous behavior (no error is thrown):
VB Code:
Private Sub frmOPC_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'
' ...
Me.CheckForIllegalCrossThreadCalls = False
'
End Sub
I include a screenshot of the green squiggle tooltip/warning.
I am looking for ideas and suggestions for a better solution to the problem than my work-around, if one exists. Questions for clarification welcome.
Last edited by Dave Sell; Sep 14th, 2009 at 03:40 PM.
Nobody knows what software they want until after you've delivered what they originally asked for.
Don't solve problems which don't exist.
"If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)
Re: System.InvalidOperationException: Cross-thread operation not valid
1. Set a control's CheckForIllegalCossThreadCalls property to False is generally not recommended.
2. To properly access a control from a different thread, you use delegate. Search the forum for "illegal cross thread" and you should find many examples showing you how to do it.
Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it. - Abraham Lincoln -
Re: System.InvalidOperationException: Cross-thread operation not valid
As stanav says, setting CheckForIllegalCrossThreadCalls to False is not generally recommended. FYI though, the reason that you get that green squiggle is because, as the error message suggests, that property is Shared. That means that you call it on the Control class, not on some instance of the Control class.