概念

AsyncTask

  • AsyncTask 系统是一套基于线程池的异步任务处理系统。每创建一个AsyncTas,都会被加入到线程池中进行执行
  • AsyncTask 泛指 FAsyncTaskFAutoDeleteAsyncTask,一般声明为友元函数,FNonAbandonableTask 派生类作为模板
  • FNonAbandonableTask 是要继承的基类,不可被终止的任务,可以看作是任务执行体的抽象

FAsyncTask

  • 模板类
  • DoWork() 实现具体任务,自定义类作为模板参数
  • FAsyncTask 初始化后,默认添加到线程池FQueuedThreadPool。可以指定其他线程池
    • StartBackgroundTask() 将任务扔到线程池中去执行
    • StartSynchronousTask() 直接在当前线程执行
  • EnsureCompletion() 可以等待任务完成
  • 执行结束需要手动停止或删除任务

FAutoDeleteAsyncTask

  • 与 FAsyncTask 类似
  • 执行结束自动删除伍。执行完成后,会通过线程池的 Destroy 函数删除,或者 DoWork 完成后删除

FQueuedThreadPool线程池

  • FQueuedThreadPool: 虚基类,定义线程池常用的接口。FQueueThreadPoolBase 继承FQueuedThreadPool,实现具体的方法。
  • FQueueThreadPoolBase 维护了多个线程FQueuedThread与多个任务队列IQueuedWork
    • TArray<IQueuedWork*> QueuedWork(要被执行的任务)
    • TArray<FQueuedThread*> QueuedThreads(空闲的线程)
    • TArray<FQueuedThread*> AllThreads(所有的线程)。
  • 线程池里的线程都是FQueuedThread类型,FQueuedThread是继承自FRunnable的线程执行体
  • FRunnableThread 表示线程本身,该类会派生出平台相关的子类

FEvent

  • FEvent: 虚基类,提供了事件操作的接口,用于线程的挂起/唤醒(Wait()/Trigger())

使用方法

FNonAbandonableTask 与 FAsyncTask

  • SimpleAsyncTask 类

    class  SimpleAsyncTask :FNonAbandonableTask
    {
    FString m_TaskName;
    int32 m_MaxNumber;
    friend class FAsyncTask<SimpleAsyncTask>;
    public:
    // 构造函数
    SimpleAsyncTask(const FString& TaskName, int32 MaxNumber)
    : m_TaskName(TaskName), m_MaxNumber(MaxNumber) {}
    // 析构函数
    ~SimpleAsyncTask()
    {
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] End"), *m_TaskName);
    } // 具体任务逻辑执行
    void DoWork()
    {
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] Start"), *m_TaskName);
    int CurrentNum = 0;
    while (CurrentNum < m_MaxNumber)
    {
    CurrentNum++;
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] CurrentNum:%d"), *m_TaskName, CurrentNum);
    }
    } // 固定写法,本类将作为函数参数
    FORCEINLINE TStatId GetStatId() const
    {
    RETURN_QUICK_DECLARE_CYCLE_STAT(SimpleAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }
    };
  • 调用任务的Actor——AAsyncTaskActor

    UFUNCTION(BlueprintCallable)
    void CreateAsyncTask(const FString& TaskName, int32 MaxNumber);
    void AAsyncTaskActor::CreateAsyncTask(const FString& TaskName, int32 MaxNumber)
    {
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] Created"), *TaskName);
    FAsyncTask<SimpleAsyncTask>* MyTask = new FAsyncTask<SimpleAsyncTask>(TaskName, MaxNumber);
    MyTask->StartBackgroundTask(); // MyTask->StartSynchronousTask; 在当前线程执行,可能会导致主线程阻塞
    // MyTask->IsDone() 可以配合定时器检测是否完成任务 //等待任务完成后,进行手动删除
    MyTask->EnsureCompletion();
    delete MyTask;
    MyTask = nullptr;
    }

FNonAbandonableTask 与 FAutoDeleteAsyncTask

  • AutoDeleteSimpleAsyncTask 类

    class  AutoDeleteSimpleAsyncTask :FNonAbandonableTask
    {
    FString m_TaskName;
    int32 m_MaxNumber;
    friend class FAutoDeleteAsyncTask<AutoDeleteSimpleAsyncTask>;
    public:
    // 构造函数
    AutoDeleteSimpleAsyncTask(const FString& TaskName, int32 MaxNumber)
    : m_TaskName(TaskName), m_MaxNumber(MaxNumber) {}
    // 析构函数
    ~AutoDeleteSimpleAsyncTask()
    {
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] End"), *m_TaskName);
    } // 具体任务逻辑执行
    void DoWork()
    {
    UE_LOG(LogTemp, Warning, TEXT("Task[%s] Start"), *m_TaskName);
    int CurrentNum = 0;
    while (CurrentNum < m_MaxNumber)
    {
    CurrentNum++;
    UE_LOG(LogTemp, Warning, TEXT("AutoDeleteTask[%s] CurrentNum:%d"), *m_TaskName, CurrentNum);
    }
    } // 固定写法,本类将作为函数参数
    FORCEINLINE TStatId GetStatId() const
    {
    RETURN_QUICK_DECLARE_CYCLE_STAT(SimpleAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }
    };
  • 调用任务的Actor——AAsyncTaskActor

    UFUNCTION(BlueprintCallable)
    void CreateAutoDeleteAsyncTask(const FString& TaskName, int32 MaxNumber);
    void AAsyncTaskActor::CreateAutoDeleteAsyncTask(const FString& TaskName, int32 MaxNumber)
    {
    UE_LOG(LogTemp, Warning, TEXT("AutoDeleteTask[%s] Created"), *TaskName);
    // 任务完成后,自动删除
    (new FAutoDeleteAsyncTask<AutoDeleteSimpleAsyncTask>(TaskName, MaxNumber))->StartSynchronousTask();
    }

参考

【UE4 C++ 基础知识】<14> 多线程——AsyncTask的更多相关文章

  1. 【UE4 C++ 基础知识】<11>资源的同步加载与异步加载

    同步加载 同步加载会造成进程阻塞. FObjectFinder / FClassFinder 在构造函数加载 ConstructorHelpers::FObjectFinder Constructor ...

  2. 【UE4 C++ 基础知识】<12> 多线程——FRunnable

    概述 UE4里,提供的多线程的方法: 继承 FRunnable 接口创建单个线程 创建 AsyncTask 调用线程池里面空闲的线程 通过 TaskGraph 系统来异步完成一些自定义任务 支持原生的 ...

  3. 【UE4 C++ 基础知识】<3> 基本数据类型、字符串处理及转换

    基本数据类型 TCHAR TCHAR就是UE4通过对char和wchar_t的封装 char ANSI编码 wchar_t 宽字符的Unicode编码 使用 TEXT() 宏包裹作为字面值 TCHAR ...

  4. 【UE4 C++ 基础知识】<13> 多线程——TaskGraph

    概述 TaskGraph 系统是UE4一套抽象的异步任务处理系统 TaskGraph 可以看作一种"基于任务的并行编程"设计思想下的实现 通过TaskGraph ,可以创建任意多线 ...

  5. JAVA基础知识之多线程——三种实现多线程的方法及区别

    所有JAVA线程都必须是Thread或其子类的实例. 继承Thread类创建线程 步骤如下, 定义Thead子类并实现run()方法,run()是线程执行体 创建此子类实例对象,即创建了线程对象 调用 ...

  6. java基础知识总结--多线程

    1.扩展Java.lang.Thread类 1.1.进程和线程的区别: 进程:每个进程都有自己独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1~n个线程. 线程:同一类线 ...

  7. 【UE4 C++ 基础知识】<5> 容器——TArray

    概述 TArray 是UE4中最常用的容器类.其速度快.内存消耗小.安全性高. 其设计时未考虑扩展问题,因此建议在实际操作中勿使用 新建(new) 和 删除(delete) 创建或销毁 TArray ...

  8. 【UE4 C++ 基础知识】<8> Delegate 委托

    概念 定义 UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系. 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到 ...

  9. JAVA基础知识之多线程——线程组和未处理异常

    线程组 Java中的ThreadGroup类表示线程组,在创建新线程时,可以通过构造函数Thread(group...)来指定线程组. 线程组具有以下特征 如果没有显式指定线程组,则新线程属于默认线程 ...

随机推荐

  1. Python__bs4模块

    1 - 导入模块 from bs4 import BeautifulSoup 2 - 创建对象 fp = open('./test.html','r',encoding='utf-8') soup = ...

  2. NOIP模拟38:b

      这是T2.   一个容斥(其实也可以欧拉反演做,但是我不会).   首先开一个桶,记录第i行的j有多少个.   然后枚举1-\(maxn\),枚举他的值域内的倍数,记录倍数在第i行有多少个,将个数 ...

  3. sql常用查询命令

    目录 SQL Server常用查询命令: 查看当前时间 查询所有数据库名 查询当前使用的数据库名 查询前几条数据 去重查询 字段换名 查询不等于 查询在两个值之间数据 查询条件或 模糊匹配查询 查询为 ...

  4. 更改已安装的织梦dedecms系统数据库表前缀

    1 修改之前我们先备份下数据,备份的操作过程是:网站后台------系统------数据库备份/还原-------然后按提交.默认保存的数据在data/backupdata目录下. 2 修改目录下da ...

  5. Nginx系列(5)- nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)

    启动Windows版本的Nginx时候,cmd报错,报错信息为[emerg] 4276#4280: bind() to 0.0.0.0:80 failed(10013: An attempt was ...

  6. cannot connect to chrome at 127.0.0.1:9222

    window10系统,先cmd打开chrome, chrome --remote-debugging-port=9222 执行脚本 from selenium import webdriver fro ...

  7. 1.3redis小结--配置php reids拓展

    1.执行php文件 输出phpinfo();  <?php phpinfo(); 2.根据PHPinfo的信息确定需要下载的 php_redis.dll , php_igbinary.dll 版 ...

  8. 浅谈语音质量保障:如何测试 RTC 中的音频质量?

    日常音视频开会中我们或多或少会遭遇这些场景:"喂喂喂,可以听到我说话吗?我听你的声音断断续续的","咦,我怎么可以听到回声?","太吵啦,我听不清楚你 ...

  9. 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么 | 百篇博客分析OpenHarmony源码 | v16.02

    百篇博客系列篇.本篇为: v16.xx 鸿蒙内核源码分析(内存规则篇) | 内存管理到底在管什么 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪 ...

  10. 《手把手教你》系列技巧篇(二十八)-java+ selenium自动化测试-处理模态对话框弹窗(详解教程)

    1.简介 在前边的文章中窗口句柄切换宏哥介绍了switchTo方法,这篇继续介绍switchTo中关于处理alert弹窗的问题.很多时候,我们进入一个网站,就会弹窗一个alert框,有些我们直接关闭, ...