如何停止导致IAsyncOperation的调用?

时间:2017-05-11 07:37:58

标签: c# asynchronous bluetooth-lowenergy 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 -Property设置为true,也是如此。电话不会停止 并且,设备在第一行之后已经通知!这不应该在调用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;
            }

        }

1 个答案:

答案 0 :(得分:0)

基于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);

甚至更低的值。