Close tabs on the next dispatcher turn - #3412
Open
FrayxRulez wants to merge 2 commits into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ArgumentException: The parameter is incorrect.(0x80070057), reported by crash telemetry on12.10.2.0, 12.10.1.0, 12.9.1.0 and 12.8.1.0 — the same call site under both the .NET Native and
the CsWinRT runtimes, so it is not new and not runtime-specific.
Where
and, below the event:
Cause
The index we pass is not the problem:
Removeresolved the item and got as far asItemCollection::RemoveAt, and theE_INVALIDARGcomes back out of XAML's ownitems-changed notification —
RaiseVectorChanged→TabViewListView::OnItemsChanged→__super::OnItemsChanged, the baseItemsControlimplementation.What every symbolicated sample has in common is how the event was delivered:
CInputServices::ProcessTouchInteractionCallback→ProcessGestureInput→RaiseDelayedPointerUpEvent. This is the touch path. XAML holds the pointer-up backduring a touch interaction to disambiguate tap from pan, then raises it from inside the
gesture engine's own callback, re-entering the dispatcher through a nested
SendMessageW.TabCloseRequestedtherefore reaches us while XAML is still walking the tree that the tabwe are about to remove is part of, and the removal fails there. No sample arrives on the
ordinary mouse
ProcessPointerInputpath, which is consistent with this only beingreproducible by touch.
Fix
Post the close to the next dispatcher turn instead of mutating
TabItemsinside the inputcallback. The count check moves with it, so it is evaluated when the removal actually happens
rather than one turn earlier.
Honest limits
The failing call returned an
HRESULT; its own frames are unwound by the time C++/WinRTthrows, so the precise precondition that
ItemsControlrejects is not recoverable from thereports. What is established is the site, that the failure is the framework's reaction to the
removal rather than a bad argument from us, and that all four symbolicated samples arrive
through the touch gesture engine. The change is sequencing, not a guard: if the mechanism is
something else, the crash will keep reporting from the dispatcher turn instead of disappearing.
Not built or run — parsed with Roslyn (
CSharpSyntaxTree.ParseText, no syntaxdiagnostics), which is a syntax check only, not a type check.