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
Use
await DeviceSearcher.SearchAsync
instead ofDeviceSearcher.SearchAsync().ContinueWith()
. This is the best way, but it will force you to make theOnStartSearchCommandExecuted
async.Remove
using
block and callDispose
manually inside.ContinueWith
(and move other post-searh logic insideContinueWith
and also do not forget callDispose
in case of exceptions (whether exception will occur in synchronous part of SearchAsync (before firstawait
) or in asynchronous part. )).