Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF TPL Restart a canceled Task

Here’s my problem: I cancel a Task with a Click Event which works fine. Now I want to restart the Task by clicking on the same start event which started the Task initially. The “error” that I get is that I get the MessageBox Information (“Stop Clicked”). So I’m “stuck” in the Cleanup Task.

How do I solve this? Help is very much appreciated.

Thank you!

Here’s my code:

public partial class MainWindow
{   CancellationTokenSource cts = new CancellationTokenSource();
    ParallelOptions po = new ParallelOptions();
}
private void Start_Click(object sender, RoutedEventArgs e)
{   var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    CancellationToken token = cts.Token;      
    ParallelOptions po = new ParallelOptions();  
    po.CancellationToken = cts.Token;
    po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;

    Task dlTask = Task.Factory.StartNew(() =>
            {   do
                {  token.ThrowIfCancellationRequested();
                   Parallel.For(0, dicQueryNoQueryURL.Count, po
                            , i =>
                            {   token.ThrowIfCancellationRequested();
                                if (!token.IsCancellationRequested){// do work
                                }
                            });
                }
                while (!token.IsCancellationRequested);
            }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
    dlTask.ContinueWith(
                (antecedents) =>
                {       if (token.IsCancellationRequested){
                        MessageBox.Show("Stop Clicked");
                    }
                    else 
                    {    MessageBox.Show("Signalling production end");   }                
                    dlTask.Dispose();
                }, uiScheduler);
}
private void btnStop_Click(object sender, RoutedEventArgs e){ cts.Cancel(); }
like image 355
user774326 Avatar asked Feb 24 '23 04:02

user774326


1 Answers

Try simply creating a new CancellationTokenSource and generating a new Token when you click Start.

private void Start_Click(object sender, RoutedEventArgs e)
{
    cts = new CancellationTokenSource();           
    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    CancellationToken token = cts.Token;
...

From the books online:

One cancellation token should refer to one "cancelable operation," however that operation may be implemented in your program. After the IsCancellationRequested property of the token has been set to true, it cannot be reset to false. Therefore, cancellation tokens cannot be reused after they have been canceled.

like image 187
Hasanain Avatar answered Mar 03 '23 15:03

Hasanain