The answer to this question is how C # Controls work
The controls in Windows Forms are tied to a specific thread and are not a safe thread. Therefore, if you call the control method from another thread, you must use one of the control call methods to marshal the call to the appropriate topic. This property can be used to determine if you should invoke the invoke method, which can be useful if you don’t know which stream belongs to the control.
From Control.InvokeRequired
Effectively, what Invoke does ensures that the code you invoke occurs in the thread that the control lives in, effectively preventing cross-thread exceptions.
From a historical point of view, in .Net 1.1, this was actually permitted. This means that you can try and execute the code in the "GUI" thread from any background thread, and this will work mostly. Sometimes it just made your application crash because you actually messed up the GUI thread while it was doing something else. This is a Cross Threaded Exception - imagine you are trying to update a TextBox while the GUI is drawing something else.
- Which action takes precedence?
- Is it possible for both to happen at once?
- What happens to all the other commands that the GUI should execute?
Effectively, you are interrupting a queue, which can have many unforeseen consequences. Invoke is a “polite” way to get what you want to do in this queue, and this rule has been enforced with .Net 2.0 using the thrown InvalidOperationException .
To understand what is really going on behind the scenes, and what is meant by a “graphics stream,” it’s useful to understand what Message Pump or Message Loop is.
In fact, this already answered the question " What is Message Pump " and it is recommended to read to understand the real mechanism that you communicate with when interacting with controls.
Other readings that may prove useful include:
What happens to Begin Invoke
One of the basic rules for programming the Windows GUI is that only the thread that created the control can access and / or change its contents (with the exception of a few documented exceptions). Try to do this from any other and you will get unpredictable behavior, from a deadlock to an exception to half the updated user interface. The correct way to update management from another thread is to send the corresponding message to the application message queue. When the message pump comes close to executing this message, the control will be updated on the same thread that created it (remember that the message pump runs on the main thread).
and for a more detailed overview of representative sample code:
Invalid multi-thread operations
Once you get an InvokeRequired score, you might consider using an extension method to transfer these calls. This is well described in the question about stack overflow. Clearing code populated by Invoke Required . "
There is also a story of a story that may be interesting .