2023/08/31_UE5.1_問題:非同期でAnyBackgroundThreadNormalTaskを使いローディングスクリーンを出そうとするとクラッシュ

問題

非同期でAnyBackgroundThreadNormalTaskを使いローディングスクリーンを出そうとするとクラッシュした。


コード

#include "Async/TaskGraphInterfaces.h"


void ULoadingScreenUserWidget::BeginLoadingScreen(ULoadingScreenUserWidget* LoadingWidget)

{

UE_LOG(LogTemp, Log, TEXT("ULoadingScreenUserWidget::BeginLoadingScreenVer1.3:AnyBackgroundThreadNormalTask"));

// このラムダ式内が別スレッド処理

// バックグラウンドスレッドで非同期タスクを作成し実行

//ラムダ式内で使用する変数にはキャプチャモードを指定する必要があります>LoadingWidget。

FFunctionGraphTask::CreateAndDispatchWhenReady([this, LoadingWidget]()

{

処理

}, TStatId(), NULL, ENamedThreads::AnyBackgroundThreadNormalTask);// バックグラウンドスレッドによる非同期タスクの実行

}


解決

バックグラウンドスレッドだとSlateにアクセスすることは許可されていないらしい。

AnyBackgroundThreadNormalTaskをGameThreadに変更してクラッシュしなくなった。


}, TStatId(), NULL, ENamedThreads::AnyBackgroundThreadNormalTask);

}, TStatId(), NULL, ENamedThreads::GameThread);


クラッシュメッセージ


LoginId:aa1f1bbf4535f59af29e15b40c3e0dba

EpicAccountId:b47207a1bd2448a8833bb07151bfe2a6


Assertion failed: IsInGameThread() || IsInSlateThread() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp] [Line: 1225] Slate can only be accessed from the GameThread or the SlateLoadingThread!


UnrealEditor_SlateCore!SWidget::Invalidate() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1225]

UnrealEditor_SlateCore!FSlateAttributeMetaData::InvalidateWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Types\SlateAttributeMetaData.cpp:369]

UnrealEditor_SlateCore!SlateAttributePrivate::TSlateAttributeBase<SWidget,EVisibility,SlateAttributePrivate::FSlateAttributeNoInvalidationReason,TSlateAttributeComparePredicate<TEqualTo<void> >,0>::Assign() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Public\Types\Attributes\SlateAttributeBase.inl:384]

UnrealEditor_SlateCore!SLeafWidget::SetVisibility() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SLeafWidget.cpp:11]

UnrealEditor_UMG!UWidget::SynchronizeProperties() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:1359]

UnrealEditor_UMG!UImage::SynchronizeProperties() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Image.cpp:46]

UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:995]

UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]

UnrealEditor_UMG!UCanvasPanelSlot::BuildSlot() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\CanvasPanelSlot.cpp:33]

UnrealEditor_UMG!UCanvasPanel::RebuildWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\CanvasPanel.cpp:59]

UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:929]

UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]

UnrealEditor_UMG!UUserWidget::RebuildWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\UserWidget.cpp:776]

UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:929]

UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]

UnrealEditor_AsyncLevelLoad!<lambda_52bd4afc06b761b81e29596b35277b24>::operator()() [C:\Users\roy00\OneDrive\Documents\Unreal Projects\PluginTest5_1\Plugins\AsyncLevelLoad\Source\AsyncLevelLoad\Private\LoadingScreenUserWidget.cpp:19]

UnrealEditor_AsyncLevelLoad!TGraphTask<TFunctionGraphTaskImpl<void __cdecl(void),0> >::ExecuteTask() [C:\Program Files\Epic Games\UE_5.1\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1348]

UnrealEditor_Core!<lambda_13c427d0bfcf321a066cb5a2badfbc27>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2051]

UnrealEditor_Core!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<<lambda_17c904c32264d0348d15245fba0e1bff>,0>::CallAndMove() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\TaskDelegate.h:171]

UnrealEditor_Core!LowLevelTasks::FTask::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\Task.h:656]

UnrealEditor_Core!LowLevelTasks::FScheduler::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:184]

UnrealEditor_Core!LowLevelTasks::FScheduler::TryExecuteTaskFrom<&LowLevelTasks::TLocalQueueRegistry<1024>::TLocalQueue::DequeueGlobal,0>() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:361]

UnrealEditor_Core!LowLevelTasks::FScheduler::WorkerMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:402]

UnrealEditor_Core!UE::Core::Private::Function::TFunctionRefCaller<<lambda_0a548c7e497de3cc77a9e48080e1524f>,void __cdecl(void)>::Call() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Templates\Function.h:475]

UnrealEditor_Core!FThreadImpl::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\Thread.cpp:67]

UnrealEditor_Core!FRunnableThreadWin::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:149]


ChatGPT


このエラーメッセージは、Slate(Unreal Engine のUIフレームワーク)のウィジェットにアクセスする際に、UIの操作はメインスレッドまたはSlateスレッドからのみ許可されているため、それ以外のスレッドからアクセスしようとしたときに発生します。SlateはUIを描画するためのスレッドセーフな仕組みを持っており、特定のスレッドからしか操作できないように制御されています。


具体的には、このエラーメッセージに示されている場所から始まり、スタックトレースを通じてコールバックチェーンを辿ることで、問題がどこで発生しているかを特定できます。


このエラーメッセージの原因は、非同期ロード中に別スレッドからUIの操作(特にSlateウィジェットの操作)を試みていることです。非同期ロードのタスクはバックグラウンドスレッドで実行されるため、Slateにアクセスすることは許可されていません。


このエラーを解決するためには、非同期ロード中にUI操作を行わず、ロード完了後にUIを更新するようにするか、非同期ロードタスク内でUI操作が必要な場合には適切なメカニズムを使用してUI操作をメインスレッドに戻す必要があります。ただし、UI操作のスレッドセーフな処理に注意する必要があります。