I see/use some form or fashion of the code all the time:
public void method1(Object sender, EventArgs args)
{
if(dataGridView1.InvokeRequired)
dataGridView1.Invoke(new EventHandler(method1), null);
else
// Do something to dataGridView1
}
My question is... What happens to the GUI thread when I use the Invoke
? Is it like an interrupt, where the thread will immediately go and execute method1
?
Is it like an interrupt...
No, not at all. There is no safe way to interrupt a thread when it is busy executing code. That causes a particularly nasty type of problem called a "re-entrancy bug". It is the kind of bug that firmware programmers battle when they implement interrupt handlers on embedded systems. Some background on that in this web page.
The UI thread of a program solves this a different way, it plays the role of the consumer in the standard solution to the Producer-consumer problem. Ingredients are a thread-safe queue that the producer posts messages to and a dispatcher loop in the consumer thread. Which retrieves messages from the queue and executes the message handler associated with the message. This is quite often described as "pumping the message loop". The producer is most commonly the operating system, generating messages for things like the user pressing a key or moving the mouse. But it can be any code that generates messages, including another thread.
Winforms adds an additional queue to this scheme, the invoke queue. Which stores the delegate object that your code created as well as the arguments you supplied. Begin/Invoke adds an entry to the invoke queue and pinvokes PostMessage() to let the UI thread know that something needs to done.
If the UI thread is busy executing code, say processing a paint event, then it is oblivious to this. It will not notice the posted message until it goes idle again, re-entering the dispatcher loop and calling GetMessage(). Or it already idle, it will then very quickly respond to the message. It retrieves the entry in the invoke queue and execute the delegate target.
In the case of Invoke instead of BeginInvoke, it will then call the Set() method of a ManualResetEvent in the queue entry. Which your thread is waiting for, it will then resume executing. If the delegate method failed then at this point the exception that was raised will also be re-raised in the thread.
Some basic conclusions you can draw from the way it works:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With