shubham Hegdey
shubham Hegdey

Reputation: 507

How to close a Thread properly in c#

I have a method that i am calling inside the Thread.Here is the Method..

 private System.Threading.Thread _thread;
 private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);

 private void DoWork()
    {
        while (!_shutdownEvent.WaitOne(0))
        { 
              //Business logic
        }
    }

and Now here i am starting the Thread..

 _thread = new Thread(DoWork);
 _thread.Start();

Now as per my requirement i want to close and restart the Thread..For Closing and restarting i am trying this code..

  _shutdownEvent.Set();  // trigger the thread to stop
  _thread.Join(); 

but i think this is not the right way to close the Thread and restart it again..

Please help me to close and restart the Thread in my case. Thanks in advance..

Upvotes: 1

Views: 408

Answers (4)

Fordio
Fordio

Reputation: 3820

You should really try to avoid managing threads yourself, and let the CLR do that for you. Creating threads is an expensive error prone activity best left alone.

The FCL provides types that you can use to manage threads. Take a look at QueueUserWorkItem which will execute some code given in a callback. This works well in situations where you just want to say "Go do something" and you don't care when/if it completes, and it has no return value. If you want to see the return value, and know when something is completed, use tasks.

I highly recommend CLR via C# by Jeffrey Richer. It has an excellent section on threading and different ways of using them in your .Net code.

Upvotes: 3

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

I'd advise you to look into the Task Parallel Library, which enables fine-grained control over its execution and supports a cancellation mechanism via the CancellationToken structure:

Here's an example:

var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;

var task = Task.Factory.StartNew(() =>
{
        // Were we already canceled?
        ct.ThrowIfCancellationRequested();

        bool moreToDo = true;
        while (moreToDo)
        {
            // Poll on this property if you have to do 
            // other cleanup before throwing. 
            if (ct.IsCancellationRequested)
            {
                // Clean up here, then...
                ct.ThrowIfCancellationRequested();
            }

        }
    }, tokenSource.Token); // Pass same token to StartNew.

tokenSource.Cancel();

Regarding "restarting the thread", you cannot restart a given Task. What you can do is see that it was canceled (A task contains a Status property which will turn into Canceled once you cancel) and if so, execute a new task.

Upvotes: 3

C.Evenhuis
C.Evenhuis

Reputation: 26446

The way you're currently waiting for the thread to finish looks fine - Threads die when they run out of code, and Join ensures that it has finished.

You cannot restart a thread though, you'll have to create a new one.

I do agree with the other answers you may want to look into the new technologies available, they allow for more readable code.

Upvotes: 2

Jodrell
Jodrell

Reputation: 35716

erm, try something modern.

private Task DoWork(CancellationToken token)
{
    while (!token.IsCancellationRequested)
    {
        // ... It would be nice if you could await something here.
    }

    return Task.FromResult(true);
}

then, just signal the CancellationToken,

using (var cts = new CancellationTokenSource())
{
    await Task.WhenAny(
        DoWork(cts.Token),
        SomeOtherWork())

    cts.Cancel();
}

Upvotes: 2

Related Questions