【发布时间】:2017-05-11 21:26:27
【问题描述】:
在我的应用程序中,我通知了多个设备。如果设备无法连接并且在几秒钟内没有响应,我想取消通话。
我的代码是: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;
}
}
【问题讨论】:
-
取消是合作的。要取消的操作需要了解取消令牌并观察取消请求。如果长时间运行的操作没有接受取消令牌的重载,则仅在其附近放置一个不会做任何事情。
-
所以您是说如果
WriteClientCharacteristicConfigurationDescriptorAsync没有带有CancellationToken 的重载,添加AsTask,不会改变任何东西吗?那么有没有办法取消这个调用呢? -
看起来不像。
-
有没有办法杀死它?以不合作的方式?
-
你试过关闭
operation.Close()的方法吗?您可以模拟需要较长时间并且可以取消的操作吗?当您在await task中等待时,看起来操作已经完成。
标签: c# asynchronous bluetooth-lowenergy iasyncoperation