简体   繁体   中英

Use a cancellation Token to cancel multiple Tasks

I want to know how to cancel Tasks. already read some articles like this: https://learn.microsoft.com/en-us/do.net/standard/threading/cancellation-in-managed-threads?redirectedfrom=MSDN

But i have already done Tasks and want to know how can i make them cancelable.

Either all at once and if that is not possible then one task should be canceled and then he should cancel the next one until all are gone.

EDIT Is that the correct using of CancellationToken? Tasks continue to run as I wanted, but when I press the cancel button I get an error. If I start my published version, the application just closes: * enter image description here

 void btnPause_Click(object sender, EventArgs e)
        {

            cts.Cancel();

        }
   

       async void btnStart_Click(object sender, EventArgs e)
    {
        try
        {
            cts = new CancellationTokenSource();
            var token = cts.Token;
            var t1 = Task.Run(() => START(token));
            await Task.WhenAny(new[] { t1 });
        }
        catch (OperationCanceledException)
        {
            // Handle canceled
        }
        catch (Exception)
        {
            // Handle other exceptions
        }
    }
    ///////////////////////////////////////////
    async void START(CancellationToken token)
    {
        for (int i = 0; i < 1; i++)
        {
            token.ThrowIfCancellationRequested();
            await Task.Delay(100, token);
             try { 
              
                    if()
                    {
                        
                    }

            }catch { }  
        }
        Thread.Sleep(2000);
        var t2 = Task.Run(() => START2(token));
        await Task.WhenAny(new[] { t2});
    }
    ///////////////////////////////////////////////
   async void START2(CancellationToken token)
    {
       
        for (int i = 0; i < 10; i++)
        {
            token.ThrowIfCancellationRequested();
            await Task.Delay(100, token);
             try { 
              
                    if()
                    {
                        
                    }

            }catch { }  
        }
        Thread.Sleep(7000);


        var t3 = Task.Run(() => MOVE(token));
        await Task.WhenAny(new[] {t3});
    }
    //////////////////////////////////////////
   async void MOVE(CancellationToken token)
    {


        for (int i = 0; i < 3; i++)
        {

            token.ThrowIfCancellationRequested();
            await Task.Delay(100, token);
            try { 
              
                    if()
                    {

                    }

            }catch { }

        }
        var t4 = Task.Run(() => MOVE2(token));
        await Task.WhenAny(new[] {t4 });

    }

Use a CancellationTokenSource, in a somewhat simplified example:

CancellationTokenSource cts = new CancellationTokenSource();
async void Cancel_Click(object sender, EventArgs e)
{
    cts.Cancel();
}
async void btnStart_Click(object sender, EventArgs e)
{
    try{
       cts = new CancellationTokenSource();
       var token = cts.Token;
       var t1 = Task.Run(() => Start(token));
       var t2 = Task.Run(() => Start(token));
       await Task.WhenAny(new []{t1, t2});
    }
    catch(OperationCancelledException){
        // Handle canceled
    }
    catch(Exception){
        // Handle other exceptions
    }
}

void Start(CancellationToken token)
{
    for (int i = 0; i < 100; i++)
    {
         token.ThrowIfCancellationRequested();
         // Do work 
         Thread.Sleep(100);
    }
}

When the button is clicked it will first create a new cancellationTokenSource, then start two tasks on background threads, both using the token from the newly created token source. When the cancelButton is pressed the token will be set into canceled-state, and the next time each background thread calls ThrowIfCancellationRequested they will throw an exception. This will put the task into a canceled-state, and awaiting this will throw an operationCancelledException that need to be caught. Note that when awaiting multiple tasks you might get an aggregateException that wraps multiple exceptions and need to be unpacked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM