A control can only be accessed by the thread that created it – this much I know.
- I have a DataGridView with a
DataSource based on a BindingList<>. - I have a worker thread (non-GUI)
that runs some fancy
calculations/comparisons/etc and
then adds/edits an object to/in the BindingList<>. - On a timer, the GUI thread refreshes itself against the BindingList<>.
This code works flawlessly – as long as I’m not running in the environment. In the environment when the .Add() method is called on the BindingList<> I get this handy little error:
An Exception has occurred
EXCEPTION : Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
IN METHOD : get_Handle
AT LINE : 0
CLASS : System.Windows.Forms.Control
Notice how the name of the control being violated is blank… I would think that if the problem was with updating the BindingList<> it wouldn’t matter if I was running in the environment or not. Notwithstanding, that’s what I’m seeing. Moreover, the .Add() completes successfully even though the exception is thrown!!
Obviously, it’s not a big deal in my production environment (yet?) since it only happens in Studio; and yes I could Invoke the GUI thread to perform the Add, or store the adds in a place for the GUI thread to retrieve them later… I’m not looking for a work-around but more so am interested in the answer to this question:
Why does the error only appear in studio?
The error may occur only in VS if it is a MDA (Managed Debugging Assistant), not a runtime exception. MDAs are there to tell you when you are doing something that is usually, but not 100% always, something that will get you in trouble in production code (which this will, eventually, even if it seems to work 99% of the time on your machine).
You should be invoking to the UI thread to perform the Add method.
EDIT: To be 100% thorough… Without Reflector (since mine expired- are you listening Red Gate?!) I am guessing that the Control class checks to see whether you are on the UI thread, throws the exception on the background thread if you are not, and then redraws the UI anyway. Since the background thread has already added the item, the UI redraw sees it and draws it to the UI as expected, but your background thread is still seeing the exception, and you are either swallowing it silently in a catch block or the background thread is being terminated (which in your app is maybe tolerable, for inst. that BG thread is a threadpool thread).