1

3日前からこれに対する答えを探してみました。それは、私が何か根本的に間違ったことをした (明らかな間違いがある) か、それが新しすぎて参照できないかのどちらかです。このような単純なケースが失敗する理由がわかりません。

次のコードは、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 スレッドであると予想されます)。私はひどく間違ったことをしましたか?

よろしくお願いします。:)

4

1 に答える 1

7

.then()UI スレッドで呼び出しているため、UI スレッドuse_current()での実行のために継続がスケジュールされます。

ただし、その継続は、UI スレッドが解放されるまで (つまり、何の作業も行っていないとき) 実行できません。しかし、あなたの例では、UI スレッドは決して解放されません。DirectXPageコンストラクターは UI スレッドで実行されています。DirectXPageコンストラクターは継続が実行されるまで返されず、継続はコンストラクターが返されるまで実行できませんDirectXPage

UI スレッドが他の作業 (継続の実行など) を自由に実行できるように、コンストラクターが戻ることを許可する必要があります。


またfileLoaded、クロススレッド通信に を使用している場合は、std::atomic<bool>またはその他の適切な同期オブジェクトを使用する必要があることに注意してください。シンプルboolでは同期には不十分です。

于 2012-10-12T16:52:25.663 に答える