C++17 异步:运行 this' 方法阻塞了整个对象

C++17 async: running a this' method blocks the whole object

我正在开发一款游戏。假设有一个对象 LoadingState 具有这些方法(以及其他一些方法):

每次 CPU 时钟滴答时都会调用更新,而创建只会调用一次,它应该调用加载函数(异步),以加载一些游戏资产。在 create 函数中异步调用 load 允许(理论上)在 create/load 执行时调用 beling 进行更新。然而,这并没有发生。

在 Visual Studio 2015 年之前,我是这样使用 std::async 的:

std::async(&LoadingState::load, this, THE_ASSETS_PATHS_STRING_VECTOR);

在迁移到 Visual Studio 2015 (C++17) 并阅读必须指定 std::launch 之后,否则可能会发生意外行为,异步现在这样调用:

std::async(std::launch::async, &LoadingState::load, this, THE_ASSETS_PATHS_STRING_VECTOR);

换句话说,在我看来 'this' 被 std::async 锁定,阻塞了整个对象,阻止了主线程调用更新。

更多相关代码:

void LoadingState::onCreate()
{
    std::vector<std::string> assets;

    assets.push_back("Images/Scenario/wall.png");
    assets.push_back("Images/Scenario/bigdummy.png");
    assets.push_back("Images/Scenario/buildings.png");
    assets.push_back("Images/Scenario/floor.png");
    assets.push_back("Images/Scenario/terrain.png");
    assets.push_back("Images/Scenario/trees.png");

    // Load assets asynchronously
    std::async(std::launch::async, &LoadingState::load, this, assets);
}

void LoadingState::load(std::vector<std::string> assets)
{
    unsigned int count = 0;
    unsigned int ratio = 100U / assets.size();

    // Cache the asset accordingly
    for (auto& asset : assets)
    {
        // Load and store the asset
        // ...

        // Asset loaded
        count++;

        // Calculate the progress by count
        m_progress = count * ratio;
    }

    // If assets were skipped or progress would be like 98% due to truncation, normalize it
    m_progress = 100U;
}


void LoadingState::update(float delta)
{
    // ...

    // If finished loading the resources, move on to playing state!
    if (m_progress >= 100U) {
        m_machine->next(new PlayingState(m_machine));
    }
}

我在这里误解了什么?!

PS:在迁移之前一切都习惯于 运行 顺利。

std::async(std::launch::async, &LoadingState::load, this, assets);

async will block in its destructor until the async function has finished 返回的 future(不同于 每个其他 future 对象)。因此,您 必须 捕获 future 并使其保持活动状态(在必要时移动它),直到您准备好回答。

或者您可以停止使用 async.

等设计不当的功能

reading that the std::launch has to be specified

不,不是。