如何在C++ WinRT控制台应用中注册事件以接收Radio状态变更通知
问题根因与修改方案
你遇到的回调不触发问题和Xaml无关,也不是必须用co_await或者Xaml专属的Dispatcher,核心是两个基础问题没处理:
1. 被监听的Radio对象生命周期不足
你在for循环中声明的局部Radio实例r,在循环迭代结束后就会被析构,注册的事件回调会跟着自动注销,自然收不到通知。你需要把需要监听的Radio实例保存到生命周期覆盖整个运行周期的容器中,比如全局变量、main函数作用域内的容器。
2. 控制台线程没有运行消息调度逻辑
WinRT的事件回调需要投递到注册线程的调度队列执行,控制台主线程默认没有启动消息循环,回调就算生成了也没有机会被执行。
完整修改后的代码示例
#include <winrt/Windows.Devices.Radios.h> #include <winrt/Windows.Foundation.h> #include <windows.h> #include <cstdio> #include <vector> using namespace winrt; using namespace Windows::Devices::Radios; // 全局容器保存被监听的Radio实例,延长生命周期 std::vector<Radio> g_monitoredRadios; void Radio_StateChanged(Radio const& sender, IInspectable const& /* args */) { printf("\t Radio_StateChanged %ls\n", sender.Name().c_str()); } void Initialize() { auto radios = Radio::GetRadiosAsync().get(); for (Radio const& r : radios) { if (r.Kind() == RadioKind::MobileBroadband) { r.StateChanged(Radio_StateChanged); g_monitoredRadios.push_back(r); printf("\t 已注册蜂窝网络Radio监听: %ls\n", r.Name().c_str()); } } } int main() { // 初始化WinRT单线程公寓 init_apartment(apartment_type::single_threaded); Initialize(); // 启动Win32消息循环,用于接收事件回调 MSG msg; while (GetMessageW(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } // 清理资源 g_monitoredRadios.clear(); uninit_apartment(); return 0; }
常见疑问解答
- 要不要用co_await:不需要,你现在用
.get()同步等待异步操作的写法完全可用,co_await只是异步非阻塞的写法,不是必须项。 - 要不要用Dispatcher:不需要Xaml框架的Dispatcher,只要跑基础的Win32消息循环就能正常接收回调。
- 要不要用Xaml:完全不需要,控制台应用不需要引入任何Xaml相关依赖就能实现该功能。
如果你选择用多线程公寓初始化(init_apartment(apartment_type::multi_threaded)),可以不用显式跑消息循环,事件回调会自动在系统线程池线程上触发,只要注意回调函数的线程安全即可。
内容的提问来源于stack exchange,提问作者user16933547
相关产品推荐
相关产品推荐

