0
auto task = create_task(Windows::Storage::KnownFolders::PicturesLibrary->GetFilesAsync(Windows::Storage::Search::CommonFileQuery::OrderBySearchRank));

task.then([&sstrpath](Windows::Foundation::Collections::IVectorView<Windows::Storage::StorageFile^>^ files)
{
    CCLog("num of files detected %d",files->Size);
    Platform::String^ pathstr = files->GetAt(0)->Path;
    OutputDebugStringW(pathstr->Data());

    auto task2 = create_task(files->GetAt(0)->OpenAsync(Windows::Storage::FileAccessMode::Read));

    task2.then([](Windows::Storage::Streams::IRandomAccessStream^ filestream)
    {
        Windows::UI::Xaml::Media::Imaging::BitmapImage^ bmp = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
        bmp->SetSource(filestream);
    }
    );
}
);

これは、C ++(cocos2dxフレームワーク)のVSExpressRTMを備えたWin8RTMで行われました。画像ライブラリから画像をロードし、そこからBitmapImageを作成しようとしています。次は、cococs2dxでCCSpriteのBitmapImageを使用することでしたが、ここでは問題ではありません。プログラムはtask2まで実行できましたが、新しいBitmmapImageを参照しようとするとクラッシュします。以下は出力コンソールにありました

First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:        
Platform::WrongThreadException ^ at memory location 0x02D1D794. HRESULT:0x8001010E
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:   
Platform::WrongThreadException ^ at memory location 0x02D1E5F0. HRESULT:0x8001010E
Unhandled exception at 0x622C9AD1 (msvcr110d.dll) in PixBlitz.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

そこにあるほとんどのチュートリアルはWin8アプリ開発用のJavascriptまたはXAMLベースであるため、私が何を間違えたかはよくわかりません。

4

1 に答える 1

0

このようなタスクを作成すると、コードが別のスレッドに移動します。間違ったスレッドからオブジェクトにアクセスすると、Platform::WrongThreadExceptionが発生します。毎回同じスレッドからGUIコンポーネントにアクセスする必要があります。

DispatcherにRunAsyncを実行すると、スレッドが正しくなると思います。デリゲートをRunAsyncに渡し、そのデリゲートにBitmapImageの作成、およびBitmapImageで実行したいその他のことを含めます。


要求に応じて、例。

私はWin8の開発に精通していませんが、それが基づいているWPFには精通しています。(C ++ / CLIがラムダをサポートしている場合は、戻って、この件に関する古い回答を修正する必要があります。)

私はこれがあなたが望むものだと信じています。そのデリゲートの構文の一部が少しずれている可能性があります。

Stream^ filesteam = files->GetAt(0)->Open(FileAccessMode::Read); // we're already on a background thread, no need for a Task if we're not going to call 'then'.

// I'm assuming 'this' is a subclass of Windows.UI.Xaml.Window, or something similar. 
this->Dispatcher->RunAsync(CoreDispatcherPriority::Low, []()
{
    BitmapImage^ bmp = ref new BitmapImage();
    bmp->SetSource(filestream);
}
);
于 2012-10-12T20:22:18.413 に答える