我刚刚开始使用WinRT的并发模型。我有一个需要等待的任务,但是调用wait()会抛出一个我无法捕获的异常。
最简单的代码:
concurrency::task<StorageFile^> getFileTask = concurrency::create_task(Windows::Storage::ApplicationData::Current->LocalFolder->GetFileAsync(fileString));
getFileTask.wait();
它抛出的例外是:
Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0402C45C
如何设置它以使其有效?
答案 0 :(得分:5)
构建Windows应用商店应用时必须遵循的最重要的规则之一是您必须永远不会阻止UI线程。从来没有。
如果您启动异步操作,则会获得future
或task
“拥有”该操作。如果在异步操作完成之前对该操作调用get()
或wait()
,则该调用将阻止直到操作完成,然后它将返回结果。
由于阻止UI线程很糟糕,如果您尝试与UI线程上尚未完成的异步操作同步,则会调用get()
或wait()
,以防止UI线程被阻止。此异常可帮助您记住不阻止UI线程。 : - )
您应该使用task
的{{3}}来提供在异步操作完成时运行的延续。如果继续需要也在UI线程上运行,请确保将task_continuation_context::use_current()
传递给then()
以确保将继续封送回UI线程以便执行。
注意:只有在使用C ++ / CX时才会抛出此异常。如果您使用的是没有C ++ / CX语言扩展的C ++,则对get()
或wait()
的调用将成功阻止,从而可能导致糟糕的用户体验。一般来说,C ++ / CX具有更多像这样的“保护轨”功能,旨在使您更容易编写好的代码。使用C ++ / CX时,您将获得C ++的全部功能,并了解错误的机会更多。