如何停止导致 IAsyncOperation 的调用?
How to stop a call resulting in 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;
现在,即使 CancellationToken 的 IsCancellationRequested-属性 设置为 true,情况也是如此。通话不会停止。
而且,设备已经在第一行之后收到 Notified!这不是应该在调用 await
之后发生吗??
是我用错了令牌还是这是一个更大的东西?
编辑
在与@Andrii 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;
}
}
基于 docs 你做得对:
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);
甚至更低的值。
在我的应用程序中,我通知了多个设备。如果某个设备在几秒钟内无法接通并且没有响应,我想取消通话。
我的代码是:
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;
现在,即使 CancellationToken 的 IsCancellationRequested-属性 设置为 true,情况也是如此。通话不会停止。
而且,设备已经在第一行之后收到 Notified!这不是应该在调用 await
之后发生吗??
是我用错了令牌还是这是一个更大的东西?
编辑
在与@Andrii 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;
}
}
基于 docs 你做得对:
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);
甚至更低的值。