Xaml CoreDispatcher.ProcessEvents()是否会导致间接崩溃?

Xaml CoreDispatcher.ProcessEvents()是否会导致间接崩溃?,xaml,microsoft-metro,windows-runtime,c++-cx,Xaml,Microsoft Metro,Windows Runtime,C++ Cx,我必须将一些旧式代码移植到Metro/WinRT(使用C++/CX),这些代码在所有地方都使用模态对话框。由于这些对话框提供自己的消息循环(使用DialogBoxParam()),因此调用代码将等待用户单击消息框上的按钮 我目前正在尝试编写一个旧MessageBox类的替代品,该类使用XAML和弹出控件。为了重现相同的行为,我必须在调用线程中等待,但也必须保持UI响应。我发现,CoreDispatcher::ProcessEvents()可以在循环中使用,以保持对事件的处理(是的,我意识到这不是

我必须将一些旧式代码移植到Metro/WinRT(使用C++/CX),这些代码在所有地方都使用模态对话框。由于这些对话框提供自己的消息循环(使用
DialogBoxParam()
),因此调用代码将等待用户单击消息框上的按钮

我目前正在尝试编写一个旧MessageBox类的替代品,该类使用XAML和弹出控件。为了重现相同的行为,我必须在调用线程中等待,但也必须保持UI响应。我发现,
CoreDispatcher::ProcessEvents()
可以在循环中使用,以保持对事件的处理(是的,我意识到这不是很好,但我不想将所有遗留代码都更改为新的线程模型)。然而,我遇到了一个问题,使我的应用程序不断崩溃

下面是一个再现问题的最小示例(只需创建一个XAML应用程序并将其连接到按钮):

void CPPXamlTest::MainPage::Button_Click_1(平台::对象^sender,Windows::UI::Xaml::路由目标^e)
{
bool cancel=false;
自动弹出=参考新弹出();
自动按钮=参考新按钮();
按钮->Content=“Boom”;
自动令牌=(按钮->单击+=ref新建RoutedEventHandler([&cancel](对象^,RoutedEventTargets^){cancel=true;});
弹出->子菜单=按钮;
弹出->等参=真;
而(!取消)
{
Window::Current->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOne和AllPending);
}
弹出->等参=假;
按钮->点击-=令牌;
}
这似乎适用于使用两个按钮打开和关闭弹出窗口的前一两次尝试。但是,尝试几次之后,应用程序将立即在
Windows.UI.Xaml.dll
中深度崩溃,同时尝试取消对空指针的引用。我也可以用C#复制这个(使用几乎相同的代码)


有人知道这里发生了什么吗?或者提供一个替代方法的建议?

如果有人感兴趣:几天后,我在MSDN论坛上问了同样的问题,得到了一位微软员工的回复:

显然,这里的问题是嵌套的消息循环,它是由在事件处理程序中调用ProcessEvents引起的。WinRT似乎不支持这一点,但这不会以定义良好的方式失败,而是会或可能导致崩溃


唉,这是我能找到的最好也是唯一的答案,所以我最终解决了这个问题,将事件处理程序(和许多其他代码)分派到另一个线程中。然后,我可以模拟
DialogBox()
/
DialogBoxParam()
(在主线程之外)的等待行为,方法是等待用户单击/点击我的XAML“dialog”弹出窗口上的按钮时发出信号的事件。

一个对我来说很好的解决方法是替换该行:

Window::Current->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
与:

有关更多信息,请参阅MSDN

auto myDispatchedHandler = ref new DispatchedHandler([&](){
   Window::Current->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}); 
dispatcher->RunAsync(CoreDispatcherPriority::Normal,myDispatchedHandler);