Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to terminate a worker thread correctly in c#

Problem statement

I have a worker thread that basically scans a folder, going into the files within it, and then sleeps for a while. The scanning operation might take 2-3 seconds but not much more. I'm looking for a way to stop this thread elegantly.

Clarification: I want to stop the thread while it's sleeping, and not while it's scanning. However, the problem is that I do not know what is the current state of the thread. If it's sleeping I want it to exit immediately. If it's scanning, I want it to exit the moment it tries to block.

Attempts at a solution

At first I was using Sleep and Interrupt. Then I found out that Interrupt doesn't really interrupt the Sleep - it only works when the threads TRIES to go into sleeping.

So I switched to Monitor Wait&Pulse. Then I found out that the Pulse only works when I'm actually in the Wait. So now I have a thread which looks like that:

while (m_shouldRun)
{
    try
    {
        DoSomethingThatTakesSeveralSeconds();
        lock (this)
        {
            Monitor.Wait(this, 5000);
        }
    }
    catch (ThreadInterruptedException)
    {
        m_shouldRun = false;
    }
}

And now I need to craft my Stop function. So I started with:

public void Stop()
{
    m_shouldRun = false;
    lock (this)
    {
        Monitor.Pulse(this);
    }
    thread.Join();
}

But this doesn't work because I may be pulsing while the thread works (while it's not waiting). So I added Interrupt:

public void Stop()
{
    m_shouldRun = false;
    thread.Interrupt();
    lock (this)
    {
        Monitor.Pulse(this);
    }
    thread.Join();
}

Another option is to use:

public void Stop()
{
    m_shouldRun = false;
    while (!thread.Join(1000))
    {
        lock (this)
        {
            Monitor.Pulse(this);
        }
    }
}

The question

What is the preferred method? Is there a third method which is preferable?

like image 366
Eldad Mor Avatar asked Sep 13 '10 08:09

Eldad Mor


People also ask

How do you terminate a thread in C?

The pthread_exit() function terminates the calling thread, making its exit status available to any waiting threads. Normally, a thread terminates by returning from the start routine that was specified in the pthread_create() call which started it.

How do I stop a worker thread?

terminate() The terminate() method of the Worker interface immediately terminates the Worker .

How do I cancel my pthreads?

Use a cancellation point: The thread terminates whenever a cancellation function is executed. When the thread must terminate, execute pthread_cancel() and wait for its termination with pthread_join() . This approach requires detailed usage of pthread_cleanup_push() and pthread_cleanup_pop() to avoid resource leakage.


2 Answers

The way to stop a thread elegantly is to leave it finish by itself. So inside the worker method you could have a boolean variable which will check whether we want to interrupt. By default it will be set to false and when you set it to true from the main thread it will simply stop the scanning operation by breaking from the processing loop.

like image 119
Darin Dimitrov Avatar answered Sep 20 '22 12:09

Darin Dimitrov


Another alternative is to use events:

private ManualResetEvent _event = new ManualResetEvent(false);


public void Run() 
{
 while (true)
 {
    DoSomethingThatTakesSeveralSeconds();
    if (_event.WaitOne(timeout))
      break;
 }
}

public void Stop() 
{
   _event.Set();
   thread.Join();
}
like image 39
liggett78 Avatar answered Sep 18 '22 12:09

liggett78