RAKESH HOLKAR RAKESH HOLKAR -4 years ago 165
C# Question

Detecting a Thread is already running in C# .net?

I am using following code.

public void runThread(){
if (System.Diagnostics.Process.GetProcessesByName("myThread").Length == 0)
{
Thread t = new Thread(new ThreadStart(go));
t.IsBackground = true;
t.Name = "myThread";
t.Start();
}
else
{
System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
}
}
public void go()
{
//My work goes here
}


I am calling runThread() function many time but i want thread only start when thread is not running. How is it possible?

Answer Source

GetProcessesByName will not look for threads in your application but for processes in your machine. In fact there is no good way to get query for the threads in your own application (a matter aside is writing a debugger).

For what you want you could create a wrapper class for your threads in such way that you could query if they are running. Or keep track of the threads yourself by other means.

You could also consider to have a Lazy<Thread> field that will be initialized when needed, and you can query to see if the thread is till alive. After testing Lazy<Thread> is not a good idea.


Derived from Simon's answer:

private int running;

public void runThread()
{
    if (Interlocked.CompareExchange(ref running, 1, 0) == 0)
    {
        Thread t = new Thread
        (
            () =>
            {
                try
                {
                    go();
                }
                catch
                {
                    //Without the catch any exceptions will be unhandled
                    //(Maybe that's what you want, maybe not*)
                }
                finally
                {
                    //Regardless of exceptions, we need this to happen:
                    running = 0;
                }
            }
        );
        t.IsBackground = true;
        t.Name = "myThread";
        t.Start();
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }   
}

public void go()
{
    //My work goes here
}

*: Gotta catch'em all


Wajid and Segey are right. You could just have a Thread field. Allow me to provide the example:

private Thread _thread;

public void runThread()
{
    var thread = _thread;
    //Prevent optimization from not using the local variable
    Thread.MemoryBarrier();
    if
    (
        thread == null ||
        thread.ThreadState == System.Threading.ThreadState.Stopped
    )
    {
        var newThread = new Thread(go);
        newThread.IsBackground = true;
        newThread.Name = "myThread";
        newThread.Start();
        //Prevent optimization from setting the field before calling Start
        Thread.MemoryBarrier();
        _thread = newThread;
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("myThreadis already Running.");
    }
}

public void go()
{
    //My work goes here
}

Note: It is better to use the first alternative (the one derived from Simon's answer) because it is thread-safe. That is, if there are various thread calling the method runThread simultaneously there is no risk of more than one thread being created.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download