Unreal Engine has a nice feature called AsyncTask
, which is used to execute a code asynchronously. It works by running certain code on a specified thread, and this functionality is mostly used when the task is heavy enough to be executed instantly without blocking the game thread.
It also provides a solution to all issues arising from multithreading, in particular, accessing parameters from one thread that are supposed to be used and/or edited in another thread. 1
AsyncTask(ENamedThreads::AnyThread, []()
{
// This code will run asynchronously, without freezing the game thread
});
You can also create nested calls to asynchronous tasks, for example:
AsyncTask(ENamedThreads::AnyThread, []()
{
// This code will run asynchronously, without freezing the game thread
AsyncTask(ENamedThreads::GameThread, []()
{
// This code will be executed on the game thread
});
});
You can also combine this with delegates and execute your code asynchronously with Blueprints
DECLARE_DYNAMIC_DELEGATE_OneParam(FAsyncDelegateExample, const TArray<float>&, OutData);
// Class, meta, etc
UFUNCTION(BlueprintCallable)
static void AddNumbersAsync(TArray<float> InData, const FAsyncDelegateExample& Result)
{
AsyncTask(ENamedThreads::AnyThread, [InData = MoveTemp(InData), Result]() mutable
{
// Just for example
for (float& InDataElement : InData)
{
InDataElement += 10;
}
AsyncTask(ENamedThreads::GameThread, [OutData = MoveTemp(InData), Result]() mutable
{
Result.ExecuteIfBound(OutData);
});
});
}
It is known that it is not possible to safely access an object from one thread that is being edited on another thread without using synchronization techniques such as mutexes . But some engine-specific code does not have these thread synchronization features, so the only way to safely access these objects is to simply access them from the desired thread ↩︎