1

C++/CX で記述された WinRT コンポーネントを使用する WinJS アプリがあります。コンポーネントは、同じスレッドからすべての呼び出しを行う必要がある、巨大なレガシー スレッドセーフでない C++ ライブラリでの作業をカプセル化するバックグラウンド スレッドを生成します。

コンポーネントのバックグラウンド スレッドがプロデューサーであり、JavaScript アプリの UI スレッドがコンシューマーであるプロデューサー/コンシューマー パターンを実装する必要があります。

JavaScript はコンポーネント メソッドを (UI スレッドで) 呼び出すことができ、C++ コードはジョブをバックグラウンド スレッドのキューにポストするため、呼び出し部分は簡単です。

問題はコールバックです。C++ バックグラウンド スレッドによって計算されたデータを UI スレッドにポストする必要があります。確かに IAsyncOperation を JavaScript に戻すことはできますが、この操作がバックグラウンド スレッドからのイベントを待機している間、UI スレッドがブロックされることは望ましくありません。

私のオプションは何ですか?

4

2 に答える 2

1

Javascript 側の C++/CX で IAsyncOperation を実装すると、promiseが公開されます。promise の実行が UI スレッドをブロックしないようにするために、次のことができます。

  • 作業のスピンを非同期に実装し (例: スレッドを使用)、コールバックを自分で管理します。
  • ラムダ式の単純なラッパーを作成するPPL ライブラリを使用します。

PPL を使用する場合、concurrency::create_async を使用してラムダを別のスレッドで実行される IAsyncOperation に変換できます。

#include <thread>
#include <ppltasks.h>
IAsyncOperation<int64>^ Class1::GetAnswer()
{ 
    return create_async([]() -> int64{
        std::this_thread::sleep_for(std::chrono::seconds(10));
        return 42;
    });
}

Javascript 側では、この IAsyncOperation を promise として使用できます。実際の作業によって UI スレッドがハングすることはありません。

var nativeObject = new CPPComponent.Class1();
  nativeObject.getAnswer().then(function(value){
    // do something with the result
  });
于 2013-03-07T23:08:47.643 に答える
0

解決しました。セクションを見てください: https://docs.microsoft.com/en-us/windows/uwp/winrt-components/walkthrough-creating-a-basic-windowsの「イベントを発生させる非同期メソッドを追加するには...」-runtime-component-in-cpp-and-calling-it-from-javascript-or-csharp .

コンポーネント クラスは、JavaScript で設定できるイベント ハンドラー (デリゲート) を宣言するという考え方です。C++ バックグラウンド スレッドは UI スレッドのコンテキストでイベントを発生させることができるため、JavaScript イベント ハンドラーは正しい方法で呼び出されます。

もちろん、これは WinJS.Promise に簡単にラップできるため、JavaScript アプリケーション コードはコンポーネントやイベントなどがあることを認識しません。

于 2013-03-20T17:08:21.890 に答える