1

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.

Laurence
  • 95
  • 11
  • Do you want a task to be cancelled after 50ms or do you want your operation to to be cancelled after 50ms? – Andrii Litvinov May 11 '17 at 12:00
  • The task "test_task". What do you mean by operation? The `await NotifyDevice(BLEDevice)` ? – Laurence May 11 '17 at 12:01
  • As far a I understand `NotifyDevice` can last longer than 50ms. Do you want it continue to run when `test_task` is cancelled after 50ms (easy solution)? – Andrii Litvinov May 11 '17 at 12:06
  • Ok here is the thing. I actually want the `NotifyDevice`-Method to get cancelled. But so far i have not found a way for this. The method i used is a wrapper for `WriteClientCharacteristicConfigurationDescriptorAsync`. I put this on another thread here on [stackoverflow](http://stackoverflow.com/questions/43909288/how-to-stop-a-call-resulting-in-iasyncoperation), but nobody seemed to be able to help me. – Laurence May 11 '17 at 12:09
  • 1
    I have posted an answer which will ensure the wrapper task will be cancelled in 50ms. I can also added comment in your other question. It should be possible to cancel `IAsyncOperation`. – Andrii Litvinov May 11 '17 at 12:29

1 Answers1

1

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; 
}
Community
  • 1
  • 1
Andrii Litvinov
  • 12,402
  • 3
  • 52
  • 59
  • Very sorry but i cant make this extension-method work with me. The compiler just wouldnt recognize the method?! – Laurence May 11 '17 at 12:59
  • Yes, you should implement it somewhere in your project. I will update my answer so that it includes it. – Andrii Litvinov May 11 '17 at 13:02
  • Sounds weird. Try to put the method in the same class, and invoke directly: `await WithCancellation(NotifyDevice(BLEDevice, cts.Token), cts.Token)` – Andrii Litvinov May 11 '17 at 13:15