学习使用FAsyncTask执行异步任务

目标

要想在另一个线程中执行代码,使用FRunnable是一种方式。而使用FAsyncTask是另一种方式(这也是UE的DDC相关代码中所使用的方式)。

本篇尝试运行一个 FAsyncTask 的最简单的例子。

1. FAsyncTask 对于任务类的要求

FAsyncTask是一个类模板:(定义在Runtime\Core\Public\Async\AsyncWork.h)

template<typename TTask>
class FAsyncTask
	: public FAsyncTaskBase
{
	...

TTask是其类型参数,即“任务类”

一个比喻:FAsyncTask是 “航班”,而 TTask 是这个航班的 “飞机”。(类似,RunnableThread是 “航班”,Runnable是 “飞机”)

FAsyncTask 对TTask是有一定要求的,因为他会调用TTask的一些函数,如果TTask这些函数调用不到则编译不会通过:
学习使用FAsyncTask执行异步任务_第1张图片
这些函数是:

  • TStatId GetStatId()
  • void DoWork() (此处定义要运行的代码)
  • bool CanAbandon()
  • void Abandon()

2. 代码例子

参照源代码文件 Runtime\Core\Public\Async\AsyncWork.h 中开头的范例。

这里定义一个测试的任务类:

class FMyTaskWorker
{
public:

	FORCEINLINE TStatId GetStatId() const
	{
		RETURN_QUICK_DECLARE_CYCLE_STAT(FMyTaskWorker, STATGROUP_ThreadPoolAsyncTasks);
	}

	//在这里定义执行的代码:
	void DoWork()
	{
		//作为测试,每1秒打印一次当前时间,执行5次
		for (int i = 0; i < 5; i++)
		{
			FPlatformProcess::Sleep(1.0f);
			UE_LOG(LogTemp, Warning, TEXT("YakSueTest: %s"), *FDateTime::Now().ToString());
		}
	}

	bool CanAbandon()
	{
		return false;
	}
	void Abandon()
	{
	}
};

想要触发时,需要先创建对象,然后使用StartBackgroundTask函数触发。为了测试,我这里在调用函数后打印一次log:

FAsyncTask<FMyTaskWorker>* AsyncTask = new FAsyncTask<FMyTaskWorker>();
AsyncTask->StartBackgroundTask();
UE_LOG(LogTemp, Warning, TEXT("YakSueTest: Function return"));

可以看到函数直接被返回,然后任务在另一个线程中逐步执行:
在这里插入图片描述

3*. 同步执行

如果在某些情况下,想要这个任务被同步执行(即在调用的线程中立即执行),则需要把StartBackgroundTask函数换为StartSynchronousTask函数:

FAsyncTask<FMyTaskWorker>* AsyncTask = new FAsyncTask<FMyTaskWorker>();
AsyncTask->StartSynchronousTask();
UE_LOG(LogTemp, Warning, TEXT("YakSueTest: Function return"));

如果是放在编辑器内触发按钮执行,则编辑器会卡住5秒执行这个任务,随后才返回函数。
在这里插入图片描述

总结

  • 使用 FAsyncTask 时,要定义一个满足要求的任务类作为其类型参数。
  • 执行时,使用StartBackgroundTask异步执行,使用StartSynchronousTask来同步执行。

你可能感兴趣的:(UE,虚幻,ue4,ue5)