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

Unreal Engine中C++/WinRT异步函数Delegate Broadcast崩溃问题求助

Unreal Engine中C++/WinRT异步语音识别触发多播委托崩溃的解决方法

问题核心

WinRT语音识别的异步回调运行在非UE游戏线程,而UE的UObject(包括多播委托)仅允许在游戏主线程操作,跨线程直接调用委托广播会触发线程安全检查崩溃——这就是同步调用正常、异步调用崩溃的根本原因。

解决步骤

1. 将委托广播切换到UE主线程执行

在WinRT的异步识别回调中,不要直接调用Broadcast(),而是通过UE的线程调度工具把广播逻辑投递到主线程:

// VoiceRecog.cpp 中异步回调内的代码替换
FString RecognizedText = ...; // 识别到的文本
AsyncTask(ENamedThreads::GameThread, [this, RecognizedText]()
{
    // 在主线程安全执行委托广播
    OnTextRecognized.Broadcast(RecognizedText);
});

WinRT的语音识别回调默认跑在系统线程池,不属于UE游戏线程,通过AsyncTask转主线程即可规避线程冲突。

2. 增加对象有效性检查

广播前确认当前UObject及绑定的Widget未被销毁,避免访问无效内存:

AsyncTask(ENamedThreads::GameThread, [this, RecognizedText]()
{
    if (this->IsValidLowLevel()) // 检查当前语音识别对象是否有效
    {
        OnTextRecognized.Broadcast(RecognizedText);
    }
});

3. 管理WinRT异步会话生命周期

在UObject销毁时,及时停止WinRT语音识别会话并释放资源,避免回调在对象销毁后触发:

void UVoiceRecog::BeginDestroy()
{
    if (SpeechRecognizer != nullptr)
    {
        SpeechRecognizer.StopRecognitionAsync().get();
        SpeechRecognizer = nullptr;
    }
    Super::BeginDestroy();
}

4. 可选:声明线程安全委托(非必须)

如果需要委托支持跨线程触发(仍建议主线程操作UObject),可以声明线程安全类型的多播委托:

// VoiceRecog.h 中委托声明
DECLARE_THREADSAFE_MULTICAST_DELEGATE_OneParam(FOnTextRecognized, FString);

验证方法

修改后重新编译项目,测试语音识别功能,此时委托广播会在主线程安全执行,蓝图Widget可正常接收并显示识别文本,不会再出现崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:20:21