Cancel superseded async page loads to fix stale-load race#100
Merged
Conversation
Page ViewModels started their data loads as fire-and-forget async work with no cancellation (HomeViewModel.Initialize and ItemDetailsViewModel.HandleParameters were async void; LibraryViewModel fired `_ = InitializeAsync()` and `_ = RefreshItemsAsync()` from every sort/filter change). A superseded load's post-await continuation could overwrite newer view-model state - for example, rapidly toggling library filters could leave the grid showing the results of an earlier selection. Introduce a small shared CancellableLoad helper that owns a CancellationTokenSource, cancels any prior in-flight load when a new one starts, and swallows the superseded OperationCanceledException. Each affected ViewModel routes its load entry points through it and threads the cancellation token into every Kiota GetAsync call, so a superseded request is cancelled at the HTTP layer. Terminal state commits are guarded with ThrowIfCancellationRequested so an already-completed request cannot write stale state, and IsLoading is only cleared by the surviving load.
CyberoniOntoni
added a commit
to CyberoniOntoni/JellyBox
that referenced
this pull request
Jun 23, 2026
Rebased onto main with conflict resolution against dfederm#93 (controller shell), dfederm#97 (packaging), and dfederm#100 (CancellableLoad). - Add shell search bar, Search page, and ShellFocusCoordinator - Fix library filter XY-focus in code-behind; up-from-home focuses search - Route collection folders via CollectionNavigation; async item lookup for search - Keep CancellableLoad for ItemDetails/SearchViewModel; add CancelAsync for navigate-away - ItemDetails null-safety and ResetDisplayState on reload
7 tasks
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.
What & why
Page ViewModels started their data loads as fire-and-forget async work with no
cancellation, so a superseded load's post-await continuation could overwrite newer
view-model state. The most reproducible case: rapidly changing a library's sort or
filters could leave the grid showing the results of an earlier selection.
This introduces a small shared
CancellableLoadhelper that owns aCancellationTokenSource, cancels any prior in-flight load when a new one starts, andswallows the superseded
OperationCanceledException.HomeViewModel,LibraryViewModel(including every sort/filter refresh path), and
ItemDetailsViewModelroute their loadentry points through it and thread the cancellation token into each Kiota
GetAsynccall,so a superseded request is cancelled at the HTTP layer. Terminal state commits are guarded
with
ThrowIfCancellationRequestedso an already-completed request can't write stale state,and
IsLoadingis only cleared by the surviving load.Type of change
Checklist
together unrelated changes.
msbuild JellyBox.sln -t:Build -p:Configuration=Debug -p:Platform=x64succeeds with 0 warnings and 0 errors.
data-loading correctness fix with no visual or layout change.
Manual test notes
Windows desktop — rapidly toggled a library's sort direction, sort option, and filters in
quick succession. The grid consistently settles on the final selection's results, and the
loading indicator clears correctly.
Screenshots / recording
N/A — no visual or layout change; this is a data-loading correctness fix.
Out of scope / follow-ups
None.