Как остановить вызов в результате IAsyncOperation?
В своем приложении я уведомляю несколько устройств. Если устройство недоступно и не отвечает в течение нескольких секунд, я хочу отменить вызов.
Мой код: await characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync
(GattClientCharacteristicConfigurationDescriptorValue.Notify);
Теперь после некоторого исследования я обнаружил, что обычно можно передать CancelationToken (_ct) и сделать это:
Сначала создайте операцию, содержащую вызов: IAsyncOperation<GattCommunicationStatus> operation = characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync
(GattClientCharacteristicConfigurationDescriptorValue.Notify);
Затем создаем задачу с CancellationToken: Task<GattCommunicationStatus> task = operation.AsTask(_ct);
А потом ждите этого: GattCommunicationStatus status = await task;
Теперь дело в том, что свойство IsCancellationRequested -Property объекта CancellationToken имеет значение true. Звонок не остановится.
И устройство получает уведомление уже после первой строки! Разве это не должно произойти после звонка await
??
Я делаю ошибку с токеном или это большая вещь?
РЕДАКТИРОВАТЬ
После разговора с @Aitrii Litvinov я добавил еще немного кода в мое первоначальное описание проблемы. Вот весь метод:
public async Task<GattCommunicationStatus> NotifyDevice(DeviceInformationDisplay deviceInfo, CancellationToken _ct)
{
try
{
BluetoothLEDevice device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
service = device.GetGattService(new Guid(Service_UUID));
characteristic0 = service.GetCharacteristics(new Guid(Characteristic_0_UUID)).First();
characteristic0.ValueChanged += characteristic0ValueChanged;
GattCommunicationStatus status = await characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
_ct.Register(() =>
{
// trying to cancel the operation somehow
});
IAsyncOperation<GattCommunicationStatus> operation = characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
Task<GattCommunicationStatus> task = operation.AsTask(_ct);
GattCommunicationStatus status_1 = await task;
if (!elapsedTimeWatcher.IsRunning)
{
elapsedTimeWatcher.Start();
}
else
{
elapsedTimeWatcher.Restart();
}
return status;
}
catch(OperationCanceledException e)
{
return GattCommunicationStatus.Unreachable;
}
catch (Exception e)
{
return GattCommunicationStatus.Unreachable;
}
}
1 ответ
Основываясь на документах, вы делаете все правильно:
try
{
...
IAsyncOperation<GattCommunicationStatus> operation =
characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
return await operation.AsTask(_ct);
...
}
...
Этот код должен зарегистрироваться на токен и позвонить operation.Cancel()
за кулисами.
Можете ли вы установить токен на более низкое значение, чтобы увидеть, действительно ли операция отменена? Сколько времени обычно требуется для выполнения метода?
Пытаться:
CancellationTokenSource cts = new CancellationTokenSource(10);
await NotifyDevice(BLEDevice, cts.Token);
Или даже более низкие значения.