1

我有一个 WinRT 应用程序,其中有一个带有Button. 该按钮打开我们的设置弹出窗口之一。为了做到这一点,按钮的Click事件是异步的。

在 Flyout 的类中,我有一个异步 Show() 方法,它返回一个 Task,很像 MessageDialogs。该方法初始化 aResultCompletionSource<object>以及 a Popup。它打开Popup,然后返回 ,ResultCompletionSource<T>.Task以便可以等待它。

为了不创建多个窗格,我将其设置Button.IsEnabledfalse在按下按钮后立即设置,并true在事件完成后将其返回(并等待任务)。

我遇到的问题是,如果用户快速单击相关按钮,最终它会导致应用程序崩溃,而且出乎意料。有时是点击 4 次后,有时是 20 次后。

我已经尝试捕获异常并找出它在调试器中的位置。找到它需要使用本机调试器进行调试(好吧,我做了混合)。该异常是源于 Windows.UI.Xaml.dll 的 win32 访问冲突异常。

是否有可能没有编组回 UI 线程?与Popup它一样具有 Flyout 的ChildLightDismissEnabled = true这就是(在这种情况下)调用Closed事件,它反过来设置 Result 的TaskCompletionSource.

一些描述问题的基本代码:

在 CustomFlyout 中:

public Task<object> ShowAsync()
{
    resultCompletionSource = new TaskCompletionSource<object>();
    parentPopup = new Popup();
    //Set all of the height/width/bounds of the popup, along with setting the Closed Event.

    parentPopup.Child = this;
    parentPopup.IsOpen = true;

    return resultCompletionSource.Task;
}

void parentPopup_Closed(object sender, object e)
{
    if(resultCompletionSource != null)
    {
        resultCompletionSource.SetResult(null);
    }

    try
    {
        (sender as Popup).Closed -= parentPopup_closed;
    }
    catch{}
}

在我的页面中单击按钮:

private async void ShowFlyout_Button_Click(object sender, RoutedEventArgs e)
{
    ShowFlyout_Button.IsEnabled = false;
    try
    {
        CustomSettingsFlyout flyout = new CustomSettingsFlyout();
        await flyout.ShowAsync()
    }
    catch{}
    finally
    {
        ShowFlyout_Button.IsEnabled = false;
    }
}

我无权访问 C UIElement 源,但调试器/反汇编器给了我这个堆栈跟踪:

>Windows.UI.Xaml.dll!CUIElement::GetRedirectionTransformsAndParentCompNode(CRenderTarget * pRenderTarget, TransformAndClipStack * pTransformsToParentCompNode, CMILMatrix * pTransformToRoot, unsigned int * pIsTransformToRootAnimating, unsigned int * pAreAllAncestorsVisible, HWCompTreeNode * * ppNearestCompNode) Line 7462   C++
Windows.UI.Xaml.dll!CUIElement::GetRedirectionTransformsAndParentCompNode(CRenderTarget * pRenderTarget, TransformAndClipStack * pTransformsToParentCompNode, CMILMatrix * pTransformToRoot, unsigned int * pIsTransformToRootAnimating, unsigned int * pAreAllAncestorsVisible, HWCompTreeNode * * ppNearestCompNode) Line 7495    C++
Windows.UI.Xaml.dll!HWWalk::RenderProperties(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int * pSkipRenderWhileInheritedCollapsed, unsigned int * pSkipRenderWhileTransparent, unsigned int * pSkipRenderWhileClippedOut, unsigned int * pSkipRenderWhileLayoutClippedOut, unsigned int * pSkipRenderWhileTransformTooSmall) Line 441   C++
Windows.UI.Xaml.dll!HWWalk::Render(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int redirectedDraw) Line 199 C++
Windows.UI.Xaml.dll!HWWalk::RenderContentAndChildren(CUIElement * pUIElement, HWRenderParams & myRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int elementHasCompNode) Line 3461    C++
Windows.UI.Xaml.dll!HWWalk::RenderProperties(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int * pSkipRenderWhileInheritedCollapsed, unsigned int * pSkipRenderWhileTransparent, unsigned int * pSkipRenderWhileClippedOut, unsigned int * pSkipRenderWhileLayoutClippedOut, unsigned int * pSkipRenderWhileTransformTooSmall) Line 629   C++
Windows.UI.Xaml.dll!HWWalk::Render(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int redirectedDraw) Line 199 C++
Windows.UI.Xaml.dll!HWWalk::RenderContentAndChildren(CUIElement * pUIElement, HWRenderParams & myRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int elementHasCompNode)  C++
Windows.UI.Xaml.dll!HWWalk::RenderProperties(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int * pSkipRenderWhileInheritedCollapsed, unsigned int * pSkipRenderWhileTransparent, unsigned int * pSkipRenderWhileClippedOut, unsigned int * pSkipRenderWhileLayoutClippedOut, unsigned int * pSkipRenderWhileTransformTooSmall) Line 629   C++
Windows.UI.Xaml.dll!HWWalk::Render(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int redirectedDraw) Line 199 C++
Windows.UI.Xaml.dll!HWWalk::RenderContentAndChildren(CUIElement * pUIElement, HWRenderParams & myRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int elementHasCompNode) Line 3461    C++
Windows.UI.Xaml.dll!HWWalk::RenderProperties(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int requiresRedirectedDrawing, unsigned int * pSkipRenderWhileInheritedCollapsed, unsigned int * pSkipRenderWhileTransparent, unsigned int * pSkipRenderWhileClippedOut, unsigned int * pSkipRenderWhileLayoutClippedOut, unsigned int * pSkipRenderWhileTransformTooSmall) Line 629   C++
Windows.UI.Xaml.dll!HWWalk::Render(CUIElement * pUIElement, const HWRenderParams & parentRP, D2DRenderContext & d2dRenderContext, unsigned int redirectedDraw) Line 199 C++
Windows.UI.Xaml.dll!HWWalk::RenderRoot(CUIElement * pVisualRoot, CRenderTarget * pRenderTarget, HWInstance * pPersistentRenderDataSentinel, HWCrossFrameResources * pCrossFrameResources, HWFrameData * pPreviousFrameData, unsigned int backgroundColor, unsigned int forceRedraw, unsigned int needsToReleaseHardwareResources, unsigned int isOverdrawHeatMapEnabled, TransformAndClipStack * pPrependTransformAndClip, const CMILMatrix & displayOrientationTransform, const CMILMatrix & displayOrientationTransformInverse, unsigned int forceAllSlotsDirty, HWCompTreeNode * * ppRootNode, BrushCloneList * * ppBrushCloneList, unsigned int * pHasRenderedContent) Line 3847    C++
Windows.UI.Xaml.dll!CCoreServices::RenderWalk(HWWalk * pHWWalk, ICoreRenderTarget * pIRenderTarget, VisualTree * pVisualTree, CSwapChainBackgroundPanel * pSCBP, unsigned int uBackgroundColor, unsigned int forceRedraw, unsigned int needsToReleaseHardwareResources, unsigned int isOverdrawHeatMapEnabled, unsigned int forceAllSlotsDirty) Line 11478  C++
Windows.UI.Xaml.dll!CCoreServices::NWDrawTree(HWWalk * pHWWalk, ICoreRenderTarget * pIRenderTarget, VisualTree * pVisualTree, unsigned int uBackgroundColor, unsigned int forceRedraw, unsigned int needsToReleaseHardwareResources, XRECT_WH * prcDirtyRect) Line 10985    C++
Windows.UI.Xaml.dll!CCoreServices::NWDrawMainTree(ICoreRenderTarget * pIRenderTarget, unsigned int fForceRedraw, unsigned int needsToReleaseHardwareResources, XRECT_WH * prcDirtyRect) Line 10697  C++
Windows.UI.Xaml.dll!CWindowRenderTarget::Draw(ICoreServices * pCore, unsigned int fForceRedraw, XRECT_WH * prcDirtyRect) Line 128   C++
Windows.UI.Xaml.dll!CXcpBrowserHost::OnTick() Line 1160 C++
Windows.UI.Xaml.dll!CXcpDispatcher::Tick() Line 1120    C++
Windows.UI.Xaml.dll!CJupiterControl::HandleWindowMessage(unsigned int uMsg, unsigned int wParam, long lParam) Line 249  C++
Windows.UI.Xaml.dll!CJupiterWindow::WindowProc(HWND__ * hwnd, unsigned int uMsg, unsigned int wParam, long lParam) Line 354 C++
Windows.UI.Xaml.dll!CJupiterWindow::StaticWindowProc(HWND__ * hwnd, unsigned int uMsg, unsigned int wParam, long lParam) Line 208   C++
user32.dll!_InternalCallWinProc@20()    Unknown
user32.dll!_UserCallWinProcCheckWow@36()    Unknown
user32.dll!_DispatchClientMessage@24()  Unknown
user32.dll!___fnDWORD@4()   Unknown
ntdll.dll!_KiUserCallbackDispatcher@12()    Unknown
Windows.UI.dll!Windows::UI::Core::CDispatcher::ProcessMessage(int bDrainQueue, int * pbAnyMessages) Line 110    C++
Windows.UI.dll!Windows::UI::Core::CDispatcher::ProcessEvents(Windows::UI::Core::CoreProcessEventsOption options) Line 184   C++
Windows.UI.Xaml.dll!CJupiterWindow::RunCoreWindowMessageLoop() Line 416 C++
Windows.UI.Xaml.dll!CJupiterControl::RunMessageLoop() Line 714  C++
Windows.UI.Xaml.dll!DirectUI::DXamlCore::RunMessageLoop() Line 2538 C++
Windows.UI.Xaml.dll!DirectUI::FrameworkView::Run() Line 91  C++
twinapi.dll!`Windows::ApplicationModel::Core::CoreApplicationViewAgileContainer::RuntimeClassInitialize'::`55'::<lambda_A2234BA2CCD64E2C>::operator()(void * pv) Line 560   C++
twinapi.dll!`Windows::ApplicationModel::Core::CoreApplicationViewAgileContainer::RuntimeClassInitialize'::`55'::<lambda_A2234BA2CCD64E2C>::<helper_func>(void * pv) Line 613    C++
SHCore.dll!_SHWaitForThreadWithWakeMask@12()    Unknown
kernel32.dll!@BaseThreadInitThunk@12()  Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8()  Unknown

我唯一能想到的是,我应该在某个地方手动编组对 UI 线程的调用CoreDispather.Invoke,但我不知道在哪里。

如果任何 MSFT-y 有源并且想要查看导致问题的文件,调试器将指向我d:\win8_gdr\windows\dxaml\xcp\core\core\elements\uielement.cpp,这显然不在我的系统上。

任何帮助将不胜感激。

4

1 回答 1

1

我似乎找到了答案,取自 SettingsFlyout 示例(但不是 Popup 示例)。

SettingsFlyout 示例已添加

parentPopup.Closed += OnPopupClosed;
Window.Current.Activated += OnWindowActivated;

到弹出窗口,方法是

private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
    {
        if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
        {
            parentPopup.IsOpen = false;
        }
    }

void OnPopupClosed(object sender, object e)
    {
        Window.Current.Activated -= OnWindowActivated;
    }

这似乎已经修复了崩溃。无论我多么大力地攻击 Show Flyout 按钮,我都无法让它重现。

于 2013-05-15T21:39:25.833 回答