Search code examples
c#taskcancellationtokensourceaggregateexception

Cancel Task and set status to "Cancelled"


I want a task to finish when the 50 Milliseconds are over. The status of the task should then be set to "Cancelled", otherwise to "RunToCompletion".

The task creation is here:

CancellationTokenSource cts = new CancellationTokenSource(50);
CancellationToken ct = cts.Token;
Task test_task = Task.Run(async () =>
{
    try
    {
        tokenS.Token.Register(() =>
        {
            cts.Cancel();
            ct.ThrowIfCancellationRequested();
        });
        await NotifyDevice(BLEDevice);
    }
    catch (Exception e)
    {
    }
},ct);

All i get till now is an AggregateException, that does not get catched somehow by the try/catch-block.


Solution

  • Here is similar question to yours: Is it possible to cancel a C# Task without a CancellationToken?. But the solution will not cancel the task in NotifyDevice method. That task can be cancelled only if underlying task supports cancellation. And based on the docs I​Async​Info can be cancelled. I would go with the wrapper to ensure the task is cancelled in 50ms in case if cancelling underlying task takes more time:

    CancellationTokenSource cts = new CancellationTokenSource(50);
    await NotifyDevice(BLEDevice, cts.Token).WithCancellation(cts.Token);
    

    EDIT: the extension method itself:

    public static async Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken) 
    { 
        var tcs = new TaskCompletionSource<bool>(); 
        using(cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) 
            if (task != await Task.WhenAny(task, tcs.Task)) 
                throw new OperationCanceledException(cancellationToken); 
        return await task; 
    }