I have tried looking for answer to this since three days back. It is either I have done something fundamentally wrong (that there's an obvious mistake) or the thing is too new to have any references, I can't seem to figure why simple cases like this would fail.

The following code uses PPL task library in C++ in a Windows Store application, simulating a file loading operation that takes 2 seconds before breaking out of the loop (of course this is to illustrate the problem with minimal codes, the real loop does other rendering to show progress, too).

The continuation part of the code (i.e. "fileLoaded = true") never gets called if I use "use_current" as the continuation context:

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);
}

The same code works if I use "use_default" or "use_arbitrary", and properly set "fileLoad" to "true". This code can be placed anywhere in a Windows Store C++ app (e.g. Direct2D app), and it would fail (I have placed it in "DirectXPage::DirectXPage" constructor body, which I expect it to be the main UI thread). Did I do something horribly wrong?

Thanks in advance for your help! :)

有帮助吗?

解决方案

Since you are calling .then() on the UI thread, use_current() will cause the continuation to be scheduled for execution on the UI thread.

However, that continuation cannot run until the UI thread is free (i.e., when it is not doing any work). But, in your example, the UI thread is never free: the DirectXPage constructor is running on the UI thread. The DirectXPage constructor will not return until the continuation executes and the continuation cannot execute until the DirectXPage constructor returns.

You need to allow the constructor to return so that the UI thread is free to do other work (like execute the continuation).


Also note that if you are using fileLoaded for cross-thread communication, you need to use an std::atomic<bool> or some other proper synchronization object. A simple bool is insufficient for synchronization.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top