Originariamente inviato da MItaly
Spiegazione rapida:
i controlli Windows Forms non sono thread-safe, ovvero se li chiami da thread diversi da quello in cui sono stati creati (ovvero, il thread che gestisce il message loop della GUI) apri la porta a potenziali race-conditions; per questo motivo, tra le altre cose, c'è una protezione che solleva un'eccezione se provi a fare una chiamata cross-thread su controlli Windows Forms.
Entra in gioco il metodo Control.Invoke.
Control.Invoke serve a chiamare il metodo specificato (tramite delegate)
dal thread della GUI, anche se la funzione che chiama Invoke si trova in un altro thread; in pratica questo accade facendo una SendMessage con un messaggio custom alla finestra in cui si trova il controllo specificato, ma quello che ti interessa è che il thread da cui chiami si mette in pausa e aspetta che il thread della GUI richiami la funzione specificata.
Nasce quindi l'"idioma" della "ctrl.InvokeRequired": per scrivere una funzione che possa essere richiamata senza problemi da qualunque thread, la funzione, prima di operare su un controllo, gli chiede se è necessario fare una Invoke (ovvero, se non siamo nel thread GUI che lo gestisce) usando la ctrl.InvokeRequired. Se non è necessaria una Invoke (ovvero, siamo già nel thread corretto) la funzione prosegue a fare quello che deve fare (ovvero, quello che accade nell'else della tua funzione). In caso contrario, la funzione
richiama sé stessa tramite la Invoke, ri-passandosi tutti i parametri; in questo caso, dato che la "nuova" chiamata è avvenuta tramite Invoke (e quindi siamo nel thread giusto) Control.InvokeRequired restituisce false e la funzione fa direttamente il suo mestiere.