我必須將一些遺留代碼移植到Metro/WinRT(使用C++/CX),並使用模式對話框。由於這些對話框提供了自己的消息循環(使用DialogBoxParam()
),調用代碼將一直等待,直到用戶單擊消息框上的一個按鈕。CoreDispatcher.ProcessEvents()會導致間接崩潰?
我正在嘗試爲舊的消息框類,它使用XAML和彈出控件編寫替換。爲了重現相同的行爲,我必須在調用線程中等待,但也必須保持UI的響應。我發現,CoreDispatcher::ProcessEvents()
可以在循環中使用,以保持處理事件(是的,我意識到這不是很漂亮,但我不想將我們的所有遺留代碼更改爲新的線程模型) 。但是,我遇到了一個問題,不斷崩潰我的應用程序。
這裏是再現這一問題的小例子(只需要創建一個XAML應用程序並將其連接到一個按鈕):
void CPPXamlTest::MainPage::Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
bool cancel = false;
auto popup = ref new Popup();
auto button = ref new Button();
button->Content = "Boom";
auto token = (button->Click += ref new RoutedEventHandler([&cancel] (Object ^, RoutedEventArgs ^) { cancel = true; }));
popup->Child = button;
popup->IsOpen = true;
while (!cancel)
{
Window::Current->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
popup->IsOpen = false;
button->Click -= token;
}
這似乎很好地打開和關閉的第一個或兩個嘗試工作彈出窗口,使用兩個按鈕。然而,經過幾次嘗試後,應用程序將立即崩潰在Windows.UI.Xaml.dll
深處,同時嘗試解引用空指針。我也可以在C#中重現這一點(使用幾乎相同的代碼)。
有沒有人有一個想法,這裏發生了什麼?或者有其他方法的建議?