You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS for Mac更新后BLE设备连接取消功能失效问题求助

解决BLE连接取消无响应的问题

首先咱们理清楚问题的来龙去脉:

你原来的代码用await device.Connect().ToTask(cancelSrc.Token),更新VS for Mac后报错,核心原因是device.Connect()的返回类型变了——它现在是void方法,不再返回可转换为Task的对象(比如之前可能返回IObservable),所以.ToTask()就没法调用了,这就是那个"operator '.' cannot be applied to operand of type void"错误的由来。

再看你现在的替代代码,问题出在这几点:

  • 你用while (!cancelSrc.Token.IsCancellationRequested)循环不断调用device.Connect(),但同步的Connect()应该是阻塞到连接成功/失败才会返回,这个循环会导致连接成功后还一直重复调用,根本停不下来
  • 循环里只在开头检查了一次取消token,一旦进入device.Connect()的阻塞状态,取消信号没法被及时捕获,所以点击取消按钮没反应

正确的处理方式

针对同步的Connect()方法,结合取消token做正确处理,分两种场景:

场景1:BLE库支持主动取消连接

如果你的BLE设备类提供了取消连接的方法(比如CancelConnection()),或者有判断连接状态的属性(比如IsConnecting),可以这么写:

using (var cancelSrc = new CancellationTokenSource())
{
    using (UserDialogs.Instance.Loading("Connecting", cancelSrc.Cancel, "Cancel"))
    {
        // 注册取消回调:用户点击取消时,主动终止连接尝试
        var cancellationRegistration = cancelSrc.Token.Register(() => 
        {
            if (device.IsConnecting) // 假设设备有这个状态属性
            {
                device.CancelConnection(); // 假设库提供取消方法
            }
        });

        try
        {
            // 把同步Connect放到Task中,同时传递取消token
            await Task.Run(() => 
            {
                // 先检查是否已取消,避免无用的连接尝试
                cancelSrc.Token.ThrowIfCancellationRequested();
                device.Connect(); // 这个方法会阻塞到连接完成/失败
            }, cancelSrc.Token);
        }
        catch (OperationCanceledException)
        {
            // 处理用户取消的逻辑,比如提示"连接已取消"
        }
        catch (Exception ex)
        {
            // 处理连接失败的其他异常,比如提示"连接失败:" + ex.Message
        }
        finally
        {
            // 释放注册的回调,避免内存泄漏
            cancellationRegistration.Dispose();
        }
    }
}

场景2:BLE库不支持主动取消

如果库没有提供取消连接的方法,咱们可以给连接加上超时,结合取消token一起处理:

using (var cancelSrc = new CancellationTokenSource())
{
    // 设置超时时间,比如10秒,超时自动取消
    cancelSrc.CancelAfter(TimeSpan.FromSeconds(10));

    using (UserDialogs.Instance.Loading("Connecting", cancelSrc.Cancel, "Cancel"))
    {
        try
        {
            await Task.Run(() => 
            {
                while (!cancelSrc.Token.IsCancellationRequested)
                {
                    // 每次循环前检查取消
                    cancelSrc.Token.ThrowIfCancellationRequested();
                    
                    // 尝试连接,假设Connect()失败会立即返回
                    if (device.TryConnect()) // 如果有TryConnect这样的非阻塞方法更好
                    {
                        break; // 连接成功,跳出循环
                    }
                    
                    // 间隔一段时间再重试,避免频繁调用
                    Task.Delay(500, cancelSrc.Token).Wait();
                }
            }, cancelSrc.Token);
        }
        catch (OperationCanceledException)
        {
            // 处理取消/超时
        }
        catch (Exception ex)
        {
            // 处理其他异常
        }
    }
}

额外建议

  • 去查一下你用的BLE库的更新文档,看看Connect()方法的变更细节——说不定库已经提供了异步版本ConnectAsync(CancellationToken token),如果有的话优先用异步方法,取消处理会更简洁自然
  • 确认device.Connect()的具体行为:是阻塞到连接成功?还是失败立即返回?不同的行为对应的处理逻辑也不一样

内容的提问来源于stack exchange,提问作者zyyphilip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:17:39