Click here to Skip to main content
15,899,314 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm a little confused about once a thread is started when does it end. Here's an example of where I'm lost at.

C#
Thread thrd = new Thread(new ThreadStart(MyMethod));
private button1_Click(object sender, EventArgs e)
{
  string myData = textBox.Text;
  thrd.Start(myData);
}
private void MyMethod(object o)
{
  // do some work with the "o" object
}


Is the thread is being started each time the button is clicked? Does the thread end once the button is clicked and therefore has to be "restarted" again.
Posted
Updated 14-Feb-11 7:36am
v2

Actually, that code won't work. Once a thread has been stopped, you can't call thread.Start on that instance again. You have to reallocate and then call Start.

C#
public class MyClass
{
    private void button1_Click(...)
    {
        string myData = textBox.Text;
        Thread myThread = new Thread(new ParameterizedThreadStart(MyMethod));
        myThread.Start(myData);
    }
}


That code will start a NEW thread each time the button is clicked. So, if you click the button three times in rapid succession, you'll end up with three threads.
 
Share this answer
 
v2
Comments
Yusuf 14-Feb-11 13:41pm    
propose as answer.
Nish Nishant 14-Feb-11 13:43pm    
Voted 5, proposed as answer. I missed that.
d.allen101 14-Feb-11 13:48pm    
so after each "run" of the button click does the previous thread "die" so-to-speak?
#realJSOP 14-Feb-11 14:29pm    
No. It will "die" when it runs out of things to do. If you want to kill it before starting a new thread, you have to do it a little differently.
I think you need to do periodic work in thread repeated from time to time. You can do it!

First of all, you should use a thread only once. Create just one thread only once in the very beginning. Start it, only once, for example, on the Form.Shown event.

Now the thread should contain an infinite look waiting for your command in the very beginning of each cycle. Don't use spin wait. You should only use thread synchronization primitives. For your purpose, use System.Threading.EventWaitHandle, System.Threading.AutoResetEvent or System.Threading.ManualResetEvent. When you call its Set method (and thread was sleeping at the call to its WaitOne method), the thread get awaken and do your task. You also need a mechanism to pass a task to the thread.

You can find even create a blocking message queues to feed task data to the thread. You can fined the most "packaged" ready-to-use solution from my Tip/Tricks article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^] (See also "alternative" (not really alternative, same thing, but the using available queue) answer for Framework v.4.0.).

In the body of your thread, you can notify your UI to update/visualize you status, results, etc. Only remember, from the thread, you cannot use UI controls directly. Instead, you should use Control.Invoke. With Invoke, you don't really call the delegate on the thread calling Invoke. Instead, the delegate and call parameters are posted on some UI queue and later removed and called directly by UI thread.

By the way, my code referenced about can give you good idea on how the invocation mechanism is implemented in UI thread.

—SA
 
Share this answer
 
Comments
Espen Harlinn 14-Feb-11 17:31pm    
Good answer, my 5
Sergey Alexandrovich Kryukov 14-Feb-11 17:33pm    
Thank you, and this one is also repeating, would be good to have some publication for reuse.
--SA
d.allen101 14-Feb-11 18:04pm    
thanks SAKryukov! you ALWAYS respond to my post on multithreading and point me in the right direction it's just that the solution requires a little effort and understanding which is fine because you always give me the CORRECT way to implement the thread! I'm going to take my time and slowly and carefully read your post and do a few more tutorials...I guess there is NO shortcut to doing this the right way. thanks again!
d.allen101 14-Feb-11 18:17pm    
SORRY forgot to thank you also Espen Harlin! the two of you(you and SAKryukov) have really gone out of your way to help me out and I'm true thankful! So thanks Harlin and SAKryukov!
Sergey Alexandrovich Kryukov 15-Feb-11 14:37pm    
If so, would you formally accept my answer?
Thank you, Allen.
--SA
The real simple solution is to use:
ThreadPool.QueueUserWorkItem[^]

More or less copied from the documentation:
using System;
using System.Threading;
public class TaskInfo 
    {
    public string Boilerplate;
    public int Value;
    public TaskInfo(string text, int number) 
    {
        Boilerplate = text;
        Value = number;
    }
}
public class Example 
{
    public static void Main()
    {
        TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);
        Console.WriteLine("Main thread exits.");
    }
    static void ThreadProc(Object stateInfo) 
    {
        TaskInfo ti = (TaskInfo) stateInfo;
        Console.WriteLine(ti.Boilerplate, ti.Value); 
    }
}


ThreadPool keeps a pool of threads around for you to use, so that you avoid the overhead of creating a new thread for each operation you want to perform in the background.

Regards
Espen Harlinn
 
Share this answer
 
Comments
Nish Nishant 14-Feb-11 17:40pm    
Most practical response, voted 5.
Espen Harlinn 14-Feb-11 18:13pm    
Thank you Nishant!
JF2015 16-Feb-11 0:55am    
Good and simple 5+
Espen Harlinn 16-Feb-11 11:20am    
Thank you JF2015!
In addition to what John said:

See the documentation: http://msdn.microsoft.com/en-us/library/6x4c42hc.aspx[^]


it states clearly: Once the thread terminates, it cannot be restarted with another call to Start.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900