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);
}
);
}
);
这是在Win8 RTM上用C ++中的VS express RTM(cocos2dx框架)完成的。我正在尝试从图片库加载图像并从中创建一个BitmapImage。接下来是以某种方式在cococs2dx中使用Cmapprite的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。
答案 0 :(得分:0)
创建类似的任务将代码移动到不同的线程上。当您从错误的线程访问对象时,您将获得Platform :: WrongThreadException。您必须每次都从同一个线程访问GUI组件。
我相信如果您将RunAsync运行到Dispatcher,那么线程就会正确。将委托传递给RunAsync,并让该委托包括创建BitmapImage,以及您想要对BitmapImage做什么。
根据要求,举个例子。
我不熟悉Win8开发,虽然我熟悉它所基于的WPF。 (如果C ++ / CLI现在支持lambdas,我将不得不回过头来修改一些关于这个主题的旧答案。)
我相信这就是你想要的。我可能会在该委托上稍微关闭一些语法。
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);
}
);