Home > Enterprise >  IsCancellationRequested is always false if CancellationTokenSource with delay
IsCancellationRequested is always false if CancellationTokenSource with delay

Time:12-25

I try to stop process by CancellationToken with timer.

But IsCancellationRequested is always false.

I tried to call cancellationToken.ThrowIfCancellationRequested(); it doesn't work.

public async Task<IReadOnlyList<ISearchableDevice>> SearchAsync(CancellationToken cancellationToken)
{
    while (!cancellationToken.IsCancellationRequested)
    {
        await Task.Delay(100, cancellationToken);
        cancellationToken.ThrowIfCancellationRequested(); // doesn't work
    }

    IReadOnlyList<ISearchableDevice> devices = new List<ISearchableDevice>();
    return devices;
}

private void OnStartSearchCommandExecuted(object? p)
{
    using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
    {
        try
        {  
             InProgress = true;
             DeviceSearcher.SearchAsync(cts.Token)
                 .ContinueWith(task =>
                 {
                  InProgress = false;

                 }, cts.Token);
         }                
         catch (Exception)
         {
                    // TODO: Add exception handling
         }
    }           
}

Where is the mistake?

CodePudding user response:

The problem is that cts is disposed before timeout is reached. More precisely, it is disposed immediately after SearchAsync reaches first await. You have at least two ways to solve this

  1. Use await DeviceSearcher.SearchAsync instead of DeviceSearcher.SearchAsync().ContinueWith(). This is the best way, but it will force you to make the OnStartSearchCommandExecuted async.

  2. Remove using block and call Dispose manually inside .ContinueWith (and move other post-searh logic inside ContinueWith and also do not forget call Dispose in case of exceptions (whether exception will occur in synchronous part of SearchAsync (before first await) or in asynchronous part. )).

  • Related