1

I guess I have simple question I used to have code:

Thread myThread = new Thread(MainProcessingThread);
myThread.IsBackground = true;
isThreadRunning = true;
myThread.Start();

and method:

 public void MainProcessingThread()
 {
 }

You can see the method above isn't static. And this code used to work. But I have passed just name of the method (not an formInstance.MainProcessingThread) to the thread above. Did I do something wrong? How did this work?

ps MainProcessingThread is a member of the main form. Can I access form member(instance) variables directly from that method?

2 Answers2

3

Given that MainProcessingThread is an instance method, the following line

Thread myThread = new Thread(MainProcessingThread);

Is a shorthand of

Thread myThread = new Thread(new ThreadStart(this.MainProcessingThread));

So, you're using the object indeed. this pointer is taken as the implicit reference. To be able to do this, you should be calling this in another instance method/property, otherwise you'll not have access to the this reference. For example if you do it in a static method, you'll get an compilation error because you don't have access to the this keyword there.

On the other hand, if the method happens to be a static one, it gets compiled into

Thread myThread = new Thread(new ThreadStart(ClassName.MainProcessingThread));
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • no this is instance method - a ok so, it means `this` is assumed - and it means I can also directly access instance variables from that method? –  May 14 '15 at 08:41
  • @user300455 Yes you can access them. But make sure you synchronize the access using some kind of `lock` – Sriram Sakthivel May 14 '15 at 08:43
  • No it will be volatile variable, like in Matt Johnsons answer here: http://stackoverflow.com/questions/12570324/c-sharp-run-a-thread-every-x-minutes-but-only-if-that-thread-is-not-running-alr#. But I will use the local variable to control if thread is still alive or not (Matt uses that volatile variable ONLY inside timer). Do you think it is very bad idea? My approach is a bit different from Matt's because I use that variable to check separate thread if it is alive, while matt is doing that check only inside timer. –  May 14 '15 at 08:46
  • 2
    @user300455 Volatile variables are not bad, but need to be used carefully if you're using it as more than just a flag. In most cases you're better off using a [Cancellation token](http://stackoverflow.com/questions/30024969/cancellationtokensource-vs-volatile-boolean) To answer your question, I need to be able to see your code. Can you please post your code with the description of what you're trying to achieve? If it is a different question from the current one, I suggest you to ask a new question instead. – Sriram Sakthivel May 14 '15 at 08:53
  • It is basically SAME as Matt Johnsons answer in here: http://stackoverflow.com/questions/12570324/c-sharp-run-a-thread-every-x-minutes-but-only-if-that-thread-is-not-running-alr#, only difference is this: http://codepad.org/n3gcD0Zs. I am interested in your opinion? –  May 14 '15 at 08:55
  • I know cancellation token might be better but this is easier for me at this point as I don't need to make much changes. I used cancellation token you suggested in other project –  May 14 '15 at 08:56
  • @user300455 No, your code is a race. If timer fired twice at the same time(which can happen with Timers.Timer and Threading.Timer), you'll end up starting two threads. You're better off using Monitor.TryEnter approach [as I explained here](http://stackoverflow.com/a/27547926/2530848) – Sriram Sakthivel May 14 '15 at 08:59
  • But this is a Windows Forms Timer. How come Matt Johnsons code doesn't have that problem then? My code is same right? –  May 14 '15 at 09:01
  • If it is a winforms timer, then there is no problem with that code. – Sriram Sakthivel May 14 '15 at 09:02
  • Note currently I am using answer from that page by Grx70 combined with your cancellationtoken –  May 14 '15 at 09:03
  • Ok so with winforms timer you think that code I showed you is reasonable? This way I have to make small changes and it suits me. Whereas if I use backgroundworker(even if it is better) I need to make lot of changes. But in other project I used your cancellation token and Grx70 answer –  May 14 '15 at 09:04
  • I'm sorry to say this. The discussion what we have here is really unrelated to the question what you have asked. Please ask new question if you have more questions(Maybe me or someone will help). If you need some clarifications in my above answer, then ask it in comments. – Sriram Sakthivel May 14 '15 at 09:06
  • OK but at least you said using that code I showed you in `codepad` with Winform Timer should be OK? –  May 14 '15 at 09:14
0

.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.

Luaan
  • 62,244
  • 7
  • 97
  • 116