Crash when invoke BlueprintImplementableEvent in FNonAbandonableTask::DoWork

I’ve wrote a blueprint function in C++ use for download URL file and save it in local disk.

It can post a http request to target URL, then received responsed data in callback function. To make sure the main thread will not been blocked by the saving action, I created a FNonAbandonableTask for saving file.

When the file has been saved, I invoke the BlueprintImplementableEvent, so that the blueprint could know the file has been saved on the disk.

And in blueprint, I overwrite the BlueprintImplementableEvent, in the function body. I tried to open the saved file throught another C++ blueprint function.

Here’s the problem,

When I call the FNonAbandonableTask in Async way(FNonAbandonableTask::StartBackgroundTask()), the Unreal Engine Editor will crash. But If I call a simple blueprint function such as PrintString, it could work.

If I call the function in Sync way(FNonAbandonableTask::StartSynchronousTask()), it could work. but the whole game will be blocked because of the file saving action.

I don’t know how to make it works better now…

Maybe I just need a way that can use in blueprint, can let me wait for a background task finish without block the game thread.

I will be very grateful for any comments and suggestions.

Here’s the following crash info:

Assertion failed: IsInGameThread() || HasAnyFlags(RF_ClassDefaultObject|RF_ArchetypeObject) || IsPostLoadThreadSafe() || IsA(UClass::StaticClass()) [File:D:/Build/++UE4+Licensee/Sync/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp] [Line: 1037]

UE4Editor_Core!AssertFailedImplV() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Misc\AssertionMacros.cpp:100]
UE4Editor_Core!FDebug::CheckVerifyFailedImpl() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Misc\AssertionMacros.cpp:450]
UE4Editor_CoreUObject!UObject::ConditionalPostLoad() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp:1037]
UE4Editor_CoreUObject!StaticDuplicateObjectEx() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\UObjectGlobals.cpp:2110]
UE4Editor_Engine!AActor::CreateComponentFromTemplate() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\ActorConstruction.cpp:989]
UE4Editor_Engine!USCS_Node::ExecuteNodeOnActor() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\SCS_Node.cpp:102]
UE4Editor_Engine!USCS_Node::ExecuteNodeOnActor() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\SCS_Node.cpp:194]
UE4Editor_Engine!USimpleConstructionScript::ExecuteScriptOnActor() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\SimpleConstructionScript.cpp:638]
UE4Editor_Engine!AActor::ExecuteConstruction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\ActorConstruction.cpp:756]
UE4Editor_Engine!AActor::FinishSpawning() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:3136]
UE4Editor_Engine!UGameplayStatics::FinishSpawningActor() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\GameplayStatics.cpp:689]
UE4Editor_Engine!UGameplayStatics::execFinishSpawningActor() [D:\Build\++UE4+Licensee\Sync\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\GameplayStatics.gen.cpp:1342]
UE4Editor_CoreUObject!UObject::execCallMathFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:860]
UE4Editor_CoreUObject!UObject::execLetObj() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:2617]
UE4Editor_CoreUObject!ProcessLocalScriptFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:997]
UE4Editor_CoreUObject!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:828]
UE4Editor_CoreUObject!ProcessLocalFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1058]
UE4Editor_CoreUObject!ProcessLocalScriptFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:997]
UE4Editor_CoreUObject!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:828]
UE4Editor_CoreUObject!ProcessLocalFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1058]
UE4Editor_CoreUObject!ProcessLocalScriptFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:997]
UE4Editor_CoreUObject!UObject::ProcessInternal() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1085]
UE4Editor_CoreUObject!UFunction::Invoke() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Class.cpp:5542]
UE4Editor_CoreUObject!UObject::ProcessEvent() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1916]
UE4Editor_Engine!AActor::ProcessEvent() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Engine\Private\Actor.cpp:798]
UE4Editor_CoreUObject!TMulticastScriptDelegate<FWeakObjectPtr>::ProcessMulticastDelegate<UObject>() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Public\UObject\ScriptDelegates.h:488]
UE4Editor_CoreUObject!FCallDelegateHelper::CallMulticastDelegate() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:2972]
UE4Editor_CoreUObject!ProcessLocalScriptFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:997]
UE4Editor_CoreUObject!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:828]
UE4Editor_CoreUObject!ProcessLocalFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1058]
UE4Editor_CoreUObject!ProcessLocalScriptFunction() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:997]
UE4Editor_CoreUObject!UObject::ProcessInternal() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1085]
UE4Editor_CoreUObject!UFunction::Invoke() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Class.cpp:5542]
UE4Editor_CoreUObject!UObject::ProcessEvent() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\ScriptCore.cpp:1916]
UE4Editor_ImageViewerAR_0719!RespDataSavingTask::DoWork() [D:\AR\Project\ImageViewerAR_RtLoad\Source\ImageViewerAR\RespDataSavingTask.cpp:35]
UE4Editor_ImageViewerAR_0719!FAutoDeleteAsyncTask<RespDataSavingTask>::DoWork() [C:\Program Files\Epic Games\UE_4.25\Engine\Source\Runtime\Core\Public\Async\AsyncWork.h:100]
UE4Editor_Core!FQueuedThread::Run() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\HAL\ThreadingBase.cpp:855]
UE4Editor_Core!FRunnableThreadWin::Run() [D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:86]

I’ve found a way that can make it work.
When invoke a BlueprintImplementableEvent in background task. It may crash.
Here’s the code:

//In BackgroundTask thread
EventsPtr->OnLocalFileSaved();

It caused by the assertion “IsInGameThread”, it looks like a protection for the thread.
So I post the invoke logic to game thread by using :

AsyncTask(ENamedThreads::GameThread,
= → void { EventsPtr->OnLocalFileSaved(); }
);

The event will also be invoked, and it can make it back to game thread.

It seems the code will not crash again. And I’ll do more testing work to make sure it has a better performance.