使用上下文"use_current"的任务继续不起作用

Task continuation with context "use_current" does not work

本文关键字:任务 继续 不起作用 current 上下文 use      更新时间:2023-10-16

从三天前开始,我就一直在寻找这个问题的答案。要么是我做了一些根本错误的事情(有一个明显的错误),要么是这件事太新了,没有任何参考,我似乎不明白为什么像这样的简单案例会失败。

以下代码在Windows应用商店应用程序中使用C++中的PPL任务库,模拟在脱离循环之前需要2秒的文件加载操作(当然,这是为了用最少的代码来说明问题,真实的循环也会进行其他渲染以显示进度)。

如果我使用"use_current"作为延续上下文,则永远不会调用代码的延续部分(即"fileLoaded=true"):

bool fileLoaded = false;
while (!fileLoaded)
{
concurrency::task<void>([this]()
{
// Simulate file load delay
concurrency::wait(2000);
}).then([this, &fileLoaded]()
{
fileLoaded = true; // This never gets executed!
// If the following is changed to "use_default" or 
// "use_arbitrary", then this continuation gets called.
}, concurrency::task_continuation_context::use_current());
concurrency::wait(50);
}

如果我使用"use_default"或"use_arbitrary",并正确地将"fileLoad"设置为"true",则相同的代码也能工作。这个代码可以放在Windows应用商店C++应用程序(例如Direct2D应用程序)中的任何位置,但它会失败(我已经把它放在"DirectXPage::DirectXPage"构造函数体中,我希望它是主UI线程)。我做错了什么吗?

提前感谢您的帮助!:)

由于您在UI线程上调用.then()use_current()将导致继续操作被安排在UI线程中执行。

但是,在UI线程空闲之前(即,当它不做任何工作时),该延续无法运行。但是,在您的示例中,UI线程从来都不是免费的:DirectXPage构造函数正在UI线程上运行。DirectXPage构造函数在continuation执行之前不会返回,而continuation在DirectXPage构造函数返回之前无法执行。

您需要允许构造函数返回,以便UI线程可以自由地执行其他工作(如执行延续)。


还要注意,如果使用fileLoaded进行跨线程通信,则需要使用std::atomic<bool>或其他适当的同步对象。一个简单的bool不足以进行同步。