Async(ParallelFor/Async)

核心特点

 
#include "Async/Async.h"

// 1. 简单的任务执行
auto Future = Async(EAsyncExecution::Thread, []() {
    return 42;
});

// 2. ParallelFor并行循环
ParallelFor(100, [](int32 Index) {
    // 并行执行
});

// 3. 更简洁的接口,封装了线程池管理
 
 

优势

  • 更简洁的API,一行代码创建异步任务
  • 自动管理线程池和任务队列
  • 内置支持多种执行策略

AsyncTask(FAsyncTask)

核心特点

 
#include "Async/TaskGraphInterfaces.h"

// 1. 需要继承自FNonAbandonableTask
class MyTask : public FNonAbandonableTask {
public:
    void DoWork() { /* 任务逻辑 */ }
    
    // 必须实现
    FORCEINLINE TStatId GetStatId() const {
        RETURN_QUICK_DECLARE_CYCLE_STAT(MyTask, STATGROUP_ThreadPoolAsyncTasks);
    }
};

// 2. 创建和执行
TUniquePtr<FAsyncTask<MyTask>> Task = MakeUnique<FAsyncTask<MyTask>>();
Task->StartBackgroundTask();  // 后台执行
Task->EnsureCompletion();      // 等待完成
 
 

优势

  • 更精细的控制,可自定义任务类
  • 性能更好,开销更小
  • 适合复杂任务,可维护状态

关键区别对比

特性
Async
AsyncTask
易用性
⭐⭐⭐⭐⭐ 非常容易
⭐⭐⭐ 需要定义类
性能
⭐⭐⭐ 有额外开销
⭐⭐⭐⭐⭐ 最优
灵活性
⭐⭐⭐ 有限
⭐⭐⭐⭐⭐ 可定制
控制粒度
粗粒度
细粒度
内存开销
较高
较低
适合场景
简单一次性任务
复杂可重用任务

技术实现差异

Async的实现本质

 
// Async内部实际上也是创建AsyncTask
template<typename T>
TFuture<T> Async(EAsyncExecution::Type ExecType, TFunction<T()>&& Function) {
    // 内部创建一个TFunctorTask
    TGraphTask<TFunctorTask<T>>::CreateTask().ConstructAndDispatchWhenReady(...);
}
 
 

AsyncTask的优势

 
// AsyncTask允许更高效的模式
class MyReusableTask : public FNonAbandonableTask {
    FThreadSafeCounter* SharedCounter;  // 可共享数据
    FEvent* CompletionEvent;           // 可同步
    
    void DoWork() {
        // 可维护复杂状态
        ProcessData(SharedData);
        CompletionEvent->Trigger();
    }
};
 
 

选择建议

使用Async的情况

 
// 1. 简单lambda任务
Async(EAsyncExecution::ThreadPool, []() {
    LoadTextureAsync();
});

// 2. 并行循环
ParallelFor(TextureArray.Num(), [&](int32 Index) {
    ProcessTexture(TextureArray[Index]);
});

// 3. 快速原型开发
 
 

使用AsyncTask的情况

 
// 1. 性能敏感的核心循环
class PhysicsUpdateTask : public FNonAbandonableTask {
    FPhysicsScene* Scene;
    float DeltaTime;
    // ...
};

// 2. 需要状态保持的任务
class AssetLoadingTask : public FNonAbandonableTask {
    TArray<FString> AssetPaths;
    TArray<UObject*> LoadedAssets;
    // ...
};

// 3. 可重用的任务模板
 
 

实际性能数据

根据官方文档和社区测试:
  • Async:创建开销≈1-2μs,适合执行时间>100μs的任务
  • AsyncTask:创建开销≈0.1-0.5μs,适合高频小任务

最佳实践示例

混合使用模式

 
// 场景:批量处理资源
void ProcessAssets(const TArray<FString>& AssetPaths) {
    // 阶段1:用AsyncTask处理每个资源(高频)
    TArray<TUniquePtr<FAsyncTask<ProcessSingleAssetTask>>> Tasks;
    for (const FString& Path : AssetPaths) {
        auto Task = MakeUnique<FAsyncTask<ProcessSingleAssetTask>>(Path);
        Task->StartBackgroundTask();
        Tasks.Add(MoveTemp(Task));
    }
    
    // 等待所有完成
    for (auto& Task : Tasks) {
        Task->EnsureCompletion();
    }
    
    // 阶段2:用Async处理后续聚合(低频)
    Async(EAsyncExecution::TaskGraphMainThread, [this]() {
        FinalizeProcessing();
    });
}
 
 

 

posted on 2026-02-04 19:58  偷懒的阿贤  阅读(0)  评论(0)    收藏  举报