Rel*_*mes 11 windows-runtime winrt-async
在Windows应用商店应用中,C++(C#虽然类似),做类似的事情
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
}.wait();
Run Code Online (Sandbox Code Playgroud)
导致未处理的异常.通常是
Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0531eb58
Run Code Online (Sandbox Code Playgroud)
在尝试使用它之前,我需要完成该操作以获取我的In App Purchase信息.这里奇怪的是除了IAsyncAction之外的任何其他东西都等待.IAsyncOperation和IAsyncOperationWithProgress工作正常,但是这个?异常然后崩溃.
说实话,我不知道IAsyncOperation和IAsyncAction之间有什么区别,它们看起来和我类似.
更新:
通过分析此页面http://msdn.microsoft.com/en-us/library/vstudio/hh750082.aspx,您可以发现IAsyncAction只是一个没有返回类型的IAsyncOperation.但是,您可以看到大多数IAsyncAction-s都是可以等待的.但真正的问题是某些Windows函数只是想在特定线程上执行(出于某种原因).ReloadSimulatorAsync就是一个很好的例子.
使用这样的代码:
void WaitForAsync( IAsyncAction ^A )
{
while(A->Status == AsyncStatus::Started)
{
std::chrono::milliseconds milis( 1 );
std::this_thread::sleep_for( milis );
}
AsyncStatus S = A->Status;
}
Run Code Online (Sandbox Code Playgroud)
导致无限循环.如果调用其他功能,它实际上是有效的.这里的问题是,如果一切都是异步,为什么需要在特定线程上执行任务?它应该是RunOn(Main/UI)Thread或类似的而不是Async.
求助,见答案;
wait
在concurrency::task
创建完之后调用完全可以消除首先要执行任务的目的。
您必须认识到,在Windows运行时中,有许多异步操作无法(或不应)在UI线程上运行(或等待)。您已经找到其中之一,现在您正在等待它。您得到了一个例外,而不是潜在地导致死锁。
为了解决这个问题,您需要使用continuation。您就在那儿;您已经在定义延续功能:
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
}).wait();
// do important things once the simulator has reloaded
important_things();
Run Code Online (Sandbox Code Playgroud)
...但是您没有使用它。任务完成后,将在UI线程中then
调用传递给您的函数。因此,您应该这样做:
IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
// do important things once the simulator has reloaded
important_things();
});
Run Code Online (Sandbox Code Playgroud)
重要的重装后代码要到任务完成后才能运行,并且它将在后台线程上运行,因此不会阻塞或死锁UI。
这是完成任务的神奇解决方案:
void WaitForAsync( IAsyncAction ^A )
{
while(A->Status == Windows::Foundation::AsyncStatus::Started)
{
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
}
Windows::Foundation::AsyncStatus S = A->Status;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13561 次 |
最近记录: |