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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:27:00