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.SearchAsyncinstead ofDeviceSearcher.SearchAsync().ContinueWith(). This is the best way, but it will force you to make theOnStartSearchCommandExecutedasync.Remove
usingblock and callDisposemanually inside.ContinueWith(and move other post-searh logic insideContinueWithand also do not forget callDisposein case of exceptions (whether exception will occur in synchronous part of SearchAsync (before firstawait) or in asynchronous part. )).
