我有一个 WinRT 应用程序,其中有一个带有Button
. 该按钮打开我们的设置弹出窗口之一。为了做到这一点,按钮的Click
事件是异步的。
在 Flyout 的类中,我有一个异步 Show() 方法,它返回一个 Task,很像 MessageDialogs。该方法初始化 aResultCompletionSource<object>
以及 a Popup
。它打开Popup
,然后返回 ,ResultCompletionSource<T>.Task
以便可以等待它。
为了不创建多个窗格,我将其设置Button.IsEnabled
为false
在按下按钮后立即设置,并true
在事件完成后将其返回(并等待任务)。
我遇到的问题是,如果用户快速单击相关按钮,最终它会导致应用程序崩溃,而且出乎意料。有时是点击 4 次后,有时是 20 次后。
我已经尝试捕获异常并找出它在调试器中的位置。找到它需要使用本机调试器进行调试(好吧,我做了混合)。该异常是源于 Windows.UI.Xaml.dll 的 win32 访问冲突异常。
是否有可能没有编组回 UI 线程?与Popup
它一样具有 Flyout 的Child
,LightDismissEnabled = 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
,这显然不在我的系统上。
任何帮助将不胜感激。