1. 源代码
AsyncWork.h
2. 多线程的使用
参考文档:https://wiki.unrealengine.com/Using_AsyncTasks
当我们需要执行一个需要很长时间的任务时,放在主线程里会导致很卡,把此任务放到其他线程里则会好很多,此时多线程就可以起到关键的作用了。
在UE4里,我们可以使用FAsyncTask 或者FAutoDeleteAsyncTask。
使用FAsyncTask 时,我们需要手动停止或删除任务;使用FAutoDeleteAsyncTask时,系统则会自动在任务结束后,删除任务。
需要先建个继承FNonAbandonableTask的类,如源码中的例子:
class ExampleAutoDeleteAsyncTask : public FNonAbandonableTask
{
friend class FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>;
int32 ExampleData;
ExampleAutoDeleteAsyncTask(int32 InExampleData)
: ExampleData(InExampleData)
{
}
void DoWork()
{
... do the work here
}
FORCEINLINE TStatId GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(ExampleAutoDeleteAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
}
};
然后具体调用就是:
void Example()
{
// start an example job
(new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartBackgroundTask();
// do an example job now, on this thread
(new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartSynchronousTask();
}
注意:StartBackgroundTask()是在另一个线程中执行此任务;StartSynchronousTask()是在当前线程中马上执行此任务。
举个例子:
.h:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Kismet/KismetSystemLibrary.h"
#include "MyActor.generated.h"
UCLASS()
class ASYNCWORKSTUDY_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
void TestAsync(FString Content);
//多线程例子
void Example();
};
class ExampleAutoDeleteAsyncTask : public FNonAbandonableTask
{
friend class FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>;
int32 ExampleData;
UObject* Object;
AMyActor* Target;
ExampleAutoDeleteAsyncTask(int32 InExampleData, UObject* InObject, AMyActor* InTarget)
: ExampleData(InExampleData),
Object(InObject),
Target(InTarget)
{
}
void DoWork()
{
UKismetSystemLibrary::PrintString(Object, FString::FromInt(ExampleData));
//调用AMyactor的测试函数
if (Target) Target->TestAsync("Success");
}
FORCEINLINE TStatId GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(ExampleAutoDeleteAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
}
};
.cpp:
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
UKismetSystemLibrary::PrintString(this, "Hello");
Example();
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMyActor::TestAsync(FString Content)
{
UKismetSystemLibrary::PrintString(this, Content);
}
void AMyActor::Example()
{
//在其他线程里执行此任务
auto task = new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(10, GetWorld(), this);
if (task) task->StartBackgroundTask();
//此任务会在当前线程中马上开始。
auto task2= new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(15, GetWorld(), this);
if (task2) task2->StartSynchronousTask();
}
来源:oschina
链接:https://my.oschina.net/u/4275499/blog/3437653