3

c++/cxStorageFile::ReadAsync()を使用して store-apps 内のファイルを読み取ろうとしましたが、常に無効な params 例外が返されます。

// "file" are returned from FileOpenPicker
IRandomAccessStream^ reader = create_task(file->OpenAsync(FileAccessMode::Read)).get();
if (reader->CanRead)
{
    BitmapImage^ b = ref new BitmapImage();
    const int count = 1000000;
    Streams::Buffer^ bb = ref new Streams::Buffer(count);
    create_task(reader->ReadAsync(bb, 1, Streams::InputStreamOptions::None)).get();
}

すべてのマニフェスト機能を有効にし、宣言用に「ファイル オープン ピッカー」と「ファイル タイプの関連付け」を追加しました。何か案は ?ありがとう!

ps: 私が見つけたほとんどのソリューションは C# 用ですが、コード構造は似ています...

4

2 に答える 2

5

このコードが UI スレッド (またはその他のシングル スレッド アパートメント、または STA) で実行され.get()ている場合、タスクがまだ完了していないと、 への呼び出しがスローされます。これは、 への呼び出しが.get()スレッドをブロックするためです。UI スレッドやその他の STA をブロックしてはなりません。C++/CX サポートを有効にしてコンパイルすると、ライブラリによってこれが強制されます。

デバッガーで初回例外処理をオンにすると ([デバッグ] -> [例外...]、[C++ 例外] チェック ボックスをオンにする)、スローされる最初の例外が例外であることがinvalid_operation、次の行からわかるはず<ppltasks.h>です。

// In order to prevent Windows Runtime STA threads from blocking the UI, calling
// task.wait() task.get() is illegal if task has not been completed.
if (!_IsCompleted() && !_IsCanceled())
{
  throw invalid_operation("Illegal to wait on a task in a Windows Runtime STA");
}

報告している「無効なパラメーター」は、この例外が ABI 境界に達したときに発生する致命的なエラーです。この例外が処理されなかったため、アプリケーションが終了しようとしていることがデバッガーに通知されます。

PPL を使用した C++ での非同期プログラミングの記事で説明されているように、を使用して継続を使用するようにコードを再構築する必要があります。task::then

于 2012-11-28T22:55:03.493 に答える
1

非同期パターンを理解していることを確認するために、コードで何が起こっているかというと、create_task を呼び出し、そのタスクが開始された直後に .get() で結果を取得しようとしています。.get() を呼び出すと、タスクがまだ実行中の場合、またはファイルが見つからない場合、すぐにスローされます。したがって、これを構造化する正しい方法は、ファイル タスクで .then を使用して、次のタスクを開始する前にこのタスクの結果を確実に取得することです。

create_task(file->OpenAsync(FileAccessMode::Read)).then([](IRandomAccessStream^ reader)
{
    //do stuff with the reader
});

その時点でリーダーが利用可能になるので、やりたいことが何でもでき、新しいタスクを開始することさえできます。

また、ファイルが空であるために OpenAsync の呼び出しが失敗している可能性があります。ファイルを取得する前のタスクに try catch ブロックを追加して、それが問題ではないことを確認します。

于 2013-05-18T20:27:19.220 に答える