How to replace material in c++ when runtime?

我想在打包好的exe中,热加载一个pak(里面包含了材质),然后使用新材质替换掉A物体的材质。
主要步骤如下:
1、从网络线程(非游戏线程)收到切换材质的消息,消息里指明pak包的绝对路径。
2、然后调用AsyncTask(ENamedThreads::GameThread, 处理函数lamda表达式)
3、然后在“处理函数lamda表达式”中,进行以下步骤:
a、将pak挂载到/Game/目录下。(挂载成功)
b、然后通过UMaterial m = (UMaterial)StaticLoadObject(UMaterial::StaticClass(), …)。 (这个步骤就会crash,报“Cannot Flush Async Loading while async loading is suspended”)

我的具体代码是:
// Fill out your copyright notice in the Description page of Project Settings.

#include “UdpControlActorImpl.h”
#include “EngineUtils.h”
#include “HAL/PlatformFilemanager.h”
#include “Runtime/Engine/Classes/Engine/StreamableManager.h”
#include “Runtime/Engine/Classes/Engine/AssetManager.h”
#include “Runtime/Engine/Classes/Engine/StaticMeshActor.h”
#include “Runtime/Engine/Classes/Engine/StaticMeshActor.h”
#include “Runtime/Engine/Classes/Materials/Material.h”
#include “Runtime/Core/Public/Templates/SharedPointer.h”
#include “IPlatformFilePak.h”

static void testLoadPak(AUdpControlActorImpl* p)
{
IPlatformFile* OldPlatform = &FPlatformFileManager::Get().GetPlatformFile();
TSharedPtr PakPlatform = MakeShareable(new FPakPlatformFile());
PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT(“”));

FPlatformFileManager::Get().SetPlatformFile(*PakPlatform.Get());

FString PakFileFullPath = L"d:/temp/dlc_myMaterial.pak";
if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*PakFileFullPath)) {
	UE_LOG(LogTemp, Warning, TEXT("%s is not exist."), *PakFileFullPath);
	return;
}

TRefCountPtr<FPakFile> TmpPak = new FPakFile(PakPlatform.Get(), *PakFileFullPath, false);
FString PakMountPoint = TmpPak->GetMountPoint();

UE_LOG(LogTemp, Warning, TEXT("mountPoint in pak is %s"), *PakMountPoint);

int32 Pos = PakMountPoint.Find("Content/");

FString NewMountPoint = PakMountPoint.RightChop(Pos);
NewMountPoint = FPaths::ProjectDir() + NewMountPoint;

UE_LOG(LogTemp, Warning, TEXT("ProjectDir is %s"), *FPaths::ProjectDir());
UE_LOG(LogTemp, Warning, TEXT("NewMountPoint is %s"), *NewMountPoint);

TmpPak->SetMountPoint(*NewMountPoint);

UMaterial* GizmoMaterial = nullptr;

if (PakPlatform->Mount(*PakFileFullPath, 1, *NewMountPoint)) {
	TArray<FString> FoundFilenames;
	TmpPak->FindFilesAtPath(FoundFilenames, *TmpPak->GetMountPoint(), true, true, true);

	if (FoundFilenames.Num() > 0) {
		UE_LOG(LogTemp, Warning, TEXT("FoundFilenames.Num() is %d"), FoundFilenames.Num());

		for (FString& Filename : FoundFilenames) {

			UE_LOG(LogTemp, Warning, TEXT(" NewFileName111 is  %s"), *Filename);
			if (Filename.EndsWith(TEXT(".uasset")) && Filename.Contains(TEXT("testMyMaterial"))) {
				NewFileName = TEXT("/Game/StarterContent/myMaterial/testMyMaterial.testMyMaterial");
				GizmoMaterial = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("/Game/StarterContent/myMaterial/testMyMaterial.testMyMaterial"));
			}

		}
	}

	for (TActorIterator<AStaticMeshActor> ActorItr(p->GetWorld()); ActorItr; ++ActorItr) {
		AStaticMeshActor* Mesh = *ActorItr;

		if (Mesh->ActorHasTag("test_chair")) {
			UStaticMeshComponent* staticMeshComponent = Mesh->GetStaticMeshComponent();
			if (GizmoMaterial) {
				UMaterialInstanceDynamic* DynamicMaterialInst = UMaterialInstanceDynamic::Create(
					GizmoMaterial, staticMeshComponent);

				staticMeshComponent->SetMaterial(0, DynamicMaterialInst);
			}
		}
	}
}

FPlatformFileManager::Get().SetPlatformFile(*OldPlatform);

}

static void test(AUdpControlActorImpl *p)
{
AsyncTask(ENamedThreads::GameThread, = {

	testLoadPak(p);
});

}

// Sets default values
AUdpControlActorImpl::AUdpControlActorImpl()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = false;

}

void AUdpControlActorImpl::BeginDestroy()
{
if (m_thread != nullptr) {
m_thread->join();
delete m_thread;
m_thread = nullptr;
}

Super::BeginDestroy();

}

// Called when the game starts or when spawned
void AUdpControlActorImpl::BeginPlay()
{
Super::BeginPlay();

if (m_thread == nullptr) {
	m_thread = new std::thread(test, this);
}

}

// Called every frame
void AUdpControlActorImpl::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}