.NET delegates have a Target
associated with them - this corresponds to the this
reference used in non-static methods wrapped by those delegates.
In your case, you're using the ThreadStart
delegate. If you explicitly create new ThreadStart(formInstance.YourMethodName
, you can query its Target
property, and see that it referes to the formInstance
.
When the delegate is invoked, this Target
value (if any) is passed as the first argument to the underlying method - what C# represents as this
reference.
To understand this a bit better, IL (the .NET's intermediate language) doesn't actually have anything like this
. It doesn't really care all too much whether your method is an instance method or a static method (note that the .NET type information does have this distinction, but not IL itself). Instead, C#'s this
is passed as the first argument to any instance method (including property accessors etc.) - this is a bit of a simplification, because you can have different calling conventions, but it's good enough for the common case. So while you can't call an instance method with any this
in C#, it's rather trivial in IL. The delegate's Invoke
method can simply pass the Target
value as the first argument and "simulate" the way C#'s this
works.
As for good practices, avoid having any access to GUI elements from other threads. It's way too easy to cause cross-thread GUI manipulation by accident and get an exception. It's actually quite easy even if you maintain reasonable separation - data binding is also dangerous.