Trevor Daniel
Trevor Daniel

Reputation: 3954

Stopping Threading

I am new to winforms programming and I am starting to work with threads.

I have managed to start a thread, but now I want to be able to click on a cancel button to stop the thread.

Here is my code so far...

This starts the thread:

private void btnSessions_Click(object sender, EventArgs e)
{
    Thread downloadThread = new Thread(new ThreadStart(DownloadThread));
    downloadThread.Start();
}

This is the thread:

void DownloadThread()
{
     // Do the work
}

This is the button I want to use to cancel the thread:

private void btnCancel_Click(object sender, EventArgs e)
{
     // Stop the thread
}

Can anyone help me work out what I need to put in btnCancel_Click please?

Upvotes: 0

Views: 110

Answers (3)

dcastro
dcastro

Reputation: 68640

You should use the Task Parallel Library (TPL) for this, which supports a natural way of canceling tasks:

private CancellationTokenSource _tokenSource2;
private CancellationToken _token;

private void btnSessions_Click(object sender, EventArgs e)
{
    _tokenSource2 = new CancellationTokenSource();
    _token = _tokenSource2.Token;

    Task task = Task.Run(() => DownloadThread(), _token);
}

private void DownloadThread()
{
    while (true)
    {
        //do work

        //cancel if needed
        if (_token.IsCancellationRequested)
        {
            _token.ThrowIfCancellationRequested();
        }
    }
}

private void btnCancel_Click(object sender, EventArgs e)
{
    // Stop the thread
    _tokenSource2.Cancel();
}

More about canceling tasks: http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

Why you should not use Thread.Abort: What's wrong with using Thread.Abort()

Upvotes: 3

Eugene
Eugene

Reputation: 1789

It's better don't use Thread and especially Thread.Abort for task like this. C# has high abstract wrapper to hide threads. Just use Task and CancellationToken. Here is example:

var cts = new CancellationTokenSource(); // define in class
CancellationToken ct = cts.Token;

private void btnSessions_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() => DownloadThread(), ct ); // start task
}

private void DownloadThread()
{
    // You need to check this at some point where cancel may occur
    if (ct.IsCancellationRequested)
        ct.ThrowIfCancellationRequested();
}

private void btnCancel_Click(object sender, EventArgs e)
{
    cancelToken.Cancel(false); // cancel task
}

More information can be found at msdn

Upvotes: 0

Peter
Peter

Reputation: 27944

You need to make the downloadThread a field in your object:

Thread downloadThread; 
private void btnSessions_Click(object sender, EventArgs e)
{
     downloadThread = new Thread(new ThreadStart(DownloadThread));
     downloadThread.Start();
}

void DownloadThread()
{
     // Do the work
}

private void btnCancel_Click(object sender, EventArgs e)
{
     downloadThread.Abort();
}

A background worker would be a better solution for ui related processing.

Upvotes: 2

Related Questions