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

如何在Xamarin.Forms应用终止时确保BLE异步关机指令发送?

解决Xamarin.Forms应用终止时BLE Shutdown指令发送问题

核心问题分析

你遇到的问题本质是:在应用终止的生命周期节点(Android OnDestroy/iOS WillTerminate)中,阻塞主线程的同步等待会触发系统任务取消(如iOS的TaskCanceledException),而完全不等待则会因进程过快结束导致异步BLE指令未发送完成。

解决方案

Android 端实现

修改OnDestroy为异步非阻塞模式,通过超时等待确保指令有足够时间发送,同时避免主线程阻塞:

protected override async void OnDestroy()
{
    try
    {
        if (_appRestartService != null)
        {
            // 设置略大于操作耗时上限的超时(如2000ms)
            await Task.WhenAny(_appRestartService.ShutDown(), Task.Delay(2000));
        }
    }
    catch (Exception ex)
    {
        // 仅记录日志,不抛出异常避免崩溃
        Console.WriteLine($"BLE shutdown failed: {ex.Message}");
    }
    base.OnDestroy();
}

iOS 端实现

利用iOS后台任务机制申请额外执行时间,确保BLE指令在进程终止前发送完成,同时不阻塞主线程:

public override void WillTerminate(UIApplication application)
{
    // 申请后台任务时间
    nint backgroundTaskId = UIApplication.SharedApplication.BeginBackgroundTask(() => 
    {
        UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskId);
        backgroundTaskId = nint.Zero;
    });

    _ = Task.Run(async () => 
    {
        try
        {
            if (_appRestartService != null)
            {
                await _appRestartService.ShutDown();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"BLE shutdown failed: {ex.Message}");
        }
        finally
        {
            // 释放后台任务资源
            if (backgroundTaskId != nint.Zero)
            {
                UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskId);
                backgroundTaskId = nint.Zero;
            }
        }
    });
}

优化ShutDown方法

确保BLE发送逻辑是真正的异步非阻塞,无需等待设备回复:

public async Task ShutDown()
{
    if (_bleConnection != null && _bleConnection.IsConnected)
    {
        var shutdownCmd = new byte[] { 0x01, 0x00 }; // 替换为你的实际指令
        await _bleConnection.WriteCharacteristicAsync(shutdownCmd);
        // 直接返回,不需要等待设备响应
    }
}

关键注意事项

  • 绝对避免在生命周期方法中使用.Wait()/.Result()阻塞主线程,否则会触发系统任务取消或应用崩溃
  • 超时时间设置需匹配BLE操作的实际耗时(建议比上限多500ms)
  • 必须捕获所有异常,防止因BLE通信失败导致应用崩溃
  • iOS端必须使用后台任务申请额外时间,否则系统会在主线程结束后立即终止所有后台任务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:40:07