本文介绍了如何停止导致IAsyncOperation的呼叫?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我通知了多个设备.如果设备无法连接并且几秒钟内没有响应,我想取消通话.

In my application I notify multiple devices. If a device is not reachable and is not responding within a few seconds, i want to cancel the call.

我的代码是:
await characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

My code is:
await characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

现在,经过一些研究,我发现通常可以传递 CancelationToken (_ct)并执行以下操作:

Now after some research i found out that usually one can pass a CancelationToken (_ct) and do this:

首先创建一个包含调用的操作:
IAsyncOperation<GattCommunicationStatus> operation = characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

First create an operation containing the call:
IAsyncOperation<GattCommunicationStatus> operation = characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

然后使用CancellationToken创建任务:
Task<GattCommunicationStatus> task = operation.AsTask(_ct);

Then creating a task with a CancellationToken:
Task<GattCommunicationStatus> task = operation.AsTask(_ct);

然后等待它:
GattCommunicationStatus status = await task;

And then await it:
GattCommunicationStatus status = await task;

现在,即使 CancellationToken IsCancellationRequested -Property设置为true,事情还是发生了.通话不会停止.
而且,设备在第一行之后已经得到已通知!是不是应该在调用await ??

Now, the thing is even though the IsCancellationRequested-Property of the CancellationToken is set to true. The call wont stop.
And, the Device is getting Notified after the first line already! Isn't that supposed to happen after the call to await??

我是否对令牌犯了错误,或者这是更大的事情了?

Do i make a mistake with the Token or is this a bigger thing?

编辑
与@Andrii Litvinov交谈之后,我在问题的初始描述中添加了更多代码.这是整个方法:

EDIT
After the conversation with @Andrii Litvinov i put some more code to my initial description of the problem. Here is the whole method:

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;
            }

        }

推荐答案

基于文档您做对了:

try
{
...

IAsyncOperation<GattCommunicationStatus> operation =
    characteristic0.WriteClientCharacteristicConfigurationDescriptorAsync(
        GattClientCharacteristicConfigurationDescriptorValue.Notify);
return await operation.AsTask(_ct);

...
}
...

此代码应注册到令牌并在后台调用operation.Cancel().

This code should register to token and call operation.Cancel() behind the scene.

您可以将令牌设置为较低的值,以查看操作是否实际上被取消了吗?通常需要多少时间来执行该方法?

Can you set a token to lower value to see if operation is actually cancelled? How much time does it normally take to execute the method?

尝试:

CancellationTokenSource cts = new CancellationTokenSource(10);
await NotifyDevice(BLEDevice, cts.Token);

甚至更低的值.

这篇关于如何停止导致IAsyncOperation的呼叫?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 06:14