Delphi FMX中BLE同步事件执行顺序异常引发访问违规问题
Delphi FMX BLE组件事件执行顺序异常引发访问违规
问题背景
最近一直在调试Delphi的BLE组件行为,始终没搞清楚问题根源,不确定是蓝牙底层、WinRT的问题,还是自己对Delphi多线程机制的理解有遗漏。
应用场景
我的FMX应用逻辑如下:
- 实例化
TBluetoothLE组件 - 为
OnDiscoverLEDevice(设备发现回调)和OnEndDiscoverDevices(发现结束回调)绑定事件处理程序 - 调用
BluetoothLE.DiscoverDevices(10000)启动10秒的设备发现流程
根据System.Bluetooth.Components.pas的源码实现逻辑,这两个事件应该在主线程串行执行,不会出现中断或并行调用的情况。
异常现象
运行过程中偶尔触发访问违规错误:
在OnDiscoverLEDevice的处理函数开头,已经检查过FStatusLabel不为nil,但执行到FStatusLabel.Text := ...赋值语句时,FStatusLabel突然变为nil,导致内存访问错误。日志输出显示,OnEndDiscoverDevices的回调(即DiscoveryFinished)似乎打断了OnDiscoverLEDevice的执行流程。
排查结果
- 已制作最小复现Demo,该问题仅在FMX环境下出现,VCL环境无此异常
- 定位到问题根源:当在
OnDiscoverLEDevice回调中访问ADevice.DeviceName时,其内部的CheckInitialized方法会执行WinRT异步操作;这些异步操作销毁时会触发CheckSynchronize,导致OnEndDiscoverDevices事件被提前加入主线程的同步队列,在OnDiscoverLEDevice的回调还未执行完成时就被调用,进而释放了FStatusLabel控件。
内容的提问来源于stack exchange,提问作者loltrol
相关产品推荐
相关产品推荐

