From 1fce082912c56b5195635090e3b213de3c7add75 Mon Sep 17 00:00:00 2001 From: Brandon Minnick <13558917+brminnick@users.noreply.github.com> Date: Fri, 10 Nov 2023 15:38:49 -0800 Subject: [PATCH] Add `CancellationToken` Parameter to Methods Returning `Task` and `ValueTask` (#1503) * Update .editorconfig * Update DrawingViewService.windows.cs * Add `CancellationToken` to IDrawingView, IAlert, AnimationBehavior * Update AvatarViewGesturesPage * Update SpeechToTextImplementation.windows.cs * Update SpeechToTextImplementation.windows.cs * Add CancellationToken * Update Unit Tests * Fix Failing Unit Tests * Remove Duplicative `ThrowIfCancellationRequested()` * Remove Duplicate `ThrowIfCancellationRequested()` * Add Timeout to `async Task` Unit Tests * Fix Unit Test Timeouts * Update `AnimateCommand` (`ICommand` -> `Command `) * `dotnet format` * Fix typo * Fix compiler bug * Update DrawingViewService.tizen.cs * Fix Unit Test Timeout * Fix BaseTest Inheritance * Refactor using TaskCompletionSource * Add CancellationToken * Increase `TestDuration.Short` * Increase to TestDuration.Long * Increase to TestDuration.Medium * Revert to `ICommand ForceValidateCommand` * Update ValidationBehavior.shared.cs * Update `void SeekTo(TimeSpan)` -> `Task SeekTo(TimeSpan, CancellationToken)` * Implement `IDisposable` pattern * Update `PlatformSeek()` * Promote PlatformSeek to `Task` * Fix Floating Point Comparison Bug * Update Windows + Tizen MediaElement * Update MauiMediaElement.windows.cs * Refactor + Optimize Code * Add CancellationToken Unit Tests for `Alerts`, `Animations` and `Behaviors` * Add CancellationToken Unit Tests for Converters * Ad Unit Tests for Extensions * Add Unit Tests for Layouts * Add CancellationToken for PopupService * Add Views CancellationToken Unit Tests * Add Default Value to CancellationToken Parameter on Public APIs * Update CONTRIBUTING.md * `dotnet format` * `dotnet format` * Update src/CommunityToolkit.Maui/Behaviors/AnimationBehavior.shared.cs * Update src/CommunityToolkit.Maui/Behaviors/AnimationBehavior.shared.cs --- .editorconfig | 5 +- CONTRIBUTING.md | 6 + .../Pages/Alerts/SnackbarPage.xaml.cs | 9 +- .../Pages/Alerts/ToastPage.xaml.cs | 10 +- .../Behaviors/AnimationBehaviorPage.xaml | 2 +- .../Behaviors/AnimationBehaviorPage.xaml.cs | 9 +- .../NumericValidationBehaviorPage.xaml.cs | 4 +- .../AvatarView/AvatarViewGesturesPage.xaml.cs | 34 ++- .../Pages/Views/DrawingViewPage.xaml.cs | 19 +- .../Pages/Views/LazyView/CustomLazyView.cs | 4 +- .../Pages/Views/LazyView/LazyViewPage.xaml | 2 +- .../Pages/Views/LazyView/LazyViewPage.xaml.cs | 7 +- .../Pages/Views/LazyView/MyLazyView.cs | 11 - .../Pages/Views/LazyView/MyViewLazyView.cs | 11 + .../Views/MediaElement/MediaElementPage.xaml | 26 +-- .../MediaElement/MediaElementPage.xaml.cs | 73 +++---- .../Views/Popup/MultiplePopupPage.xaml.cs | 20 +- .../Popup/ShowPopupInOnAppearingPage.xaml.cs | 4 +- .../Behaviors/AnimationBehaviorViewModel.cs | 2 +- ...yteArrayToImageSourceConverterViewModel.cs | 8 +- .../ItemTappedEventArgsConverterViewModel.cs | 4 +- .../Essentials/SpeechToTextViewModel.cs | 10 +- .../Extensions/KeyboardExtensionsViewModel.cs | 2 +- .../Layouts/StateContainerViewModel.cs | 8 +- .../ViewModels/Views/DrawingViewViewModel.cs | 2 +- .../CustomSizeAndPositionPopupViewModel.cs | 6 +- .../Views/Popup/MultiplePopupViewModel.cs | 10 +- .../Views/Popups/ButtonPopup.xaml.cs | 6 +- .../Views/Popups/MultipleButtonPopup.xaml.cs | 12 +- .../Popups/NoOutsideTapDismissPopup.xaml.cs | 6 +- .../Views/Popups/ReturnResultPopup.xaml.cs | 6 +- .../Views/Popups/TransparentPopup.xaml.cs | 3 +- .../Essentials/FileSaver/FileSaver.shared.cs | 4 +- .../FileSaverImplementation.shared.cs | 4 +- .../Essentials/FileSaver/IFileSaver.shared.cs | 4 +- .../FolderPicker/FolderPicker.shared.cs | 2 +- .../FolderPickerImplementation.shared.cs | 4 +- .../FolderPicker/IFolderPicker.shared.cs | 4 +- .../SpeechToText/ISpeechToText.shared.cs | 8 +- ...SharedSpeechToTextImplementation.macios.cs | 2 +- .../SpeechToText/SpeechToText.shared.cs | 8 +- .../SpeechToTextImplementation.shared.cs | 8 +- .../SpeechToTextImplementation.tizen.cs | 6 +- .../SpeechToTextImplementation.windows.cs | 11 +- .../IPopupService.cs | 9 +- .../Interfaces/IDrawingLine.shared.cs | 3 +- .../Interfaces/IDrawingView.shared.cs | 3 +- .../KeyboardExtensions.shared.cs | 4 +- .../Views/DrawingView/DrawingLine.shared.cs | 13 +- .../Service/DrawingViewService.android.cs | 17 +- .../Service/DrawingViewService.macios.cs | 20 +- .../Service/DrawingViewService.net.cs | 16 +- .../Service/DrawingViewService.tizen.cs | 26 ++- .../Service/DrawingViewService.windows.cs | 21 +- .../Handlers/MediaElementHandler.shared.cs | 52 ++--- .../IAsynchronousMediaElementHandler.cs | 12 ++ .../Interfaces/IMediaElement.cs | 5 +- .../MediaElement.shared.cs | 84 ++++++-- .../Views/MauiMediaElement.windows.cs | 26 ++- .../Views/MediaManager.android.cs | 79 ++++--- .../Views/MediaManager.macios.cs | 86 ++++---- .../Views/MediaManager.shared.cs | 20 +- .../Views/MediaManager.tizen.cs | 27 +-- .../Views/MediaManager.windows.cs | 103 ++++----- .../Generators/TextColorToGenerator.cs | 6 +- .../Alerts/SnackbarTests.cs | 88 ++++++-- .../Alerts/ToastTests.cs | 58 +++++- .../Animations/FadeAnimationTests.cs | 44 +++- .../BaseTest.cs | 7 + .../Behaviors/AnimationBehaviorTests.cs | 96 ++++++++- .../CharactersValidationBehaviorTests.cs | 50 ++++- .../Behaviors/EmailValidationBehaviorTests.cs | 47 ++++- .../Behaviors/IconTintColorBehaviorTests.cs | 2 - .../Behaviors/MultiValidationBehaviorTests.cs | 58 +++++- .../NumericValidationBehaviorTests.cs | 58 +++++- .../Behaviors/TextValidationBehaviorTests.cs | 50 ++++- .../Behaviors/UriValidationBehaviorTests.cs | 50 ++++- .../UserStoppedTypingBehaviorTests.cs | 197 +++++++++++++----- .../Behaviors/ValidationBehaviorTests.cs | 68 +++++- .../CommunityToolkit.Maui.UnitTests.csproj | 1 + .../ByteArrayToImageSourceConverterTests.cs | 2 +- .../Converters/ImageResourceConverterTests.cs | 38 +++- .../Essentials/BadgeTests.cs | 2 +- .../Essentials/FileSaverTests.cs | 6 +- .../Essentials/FolderPickerTests.cs | 6 +- .../Essentials/SpeechToTextTests.cs | 23 +- .../Extensions/BackgroundColorToTests.cs | 36 +++- .../ColorConversionExtensionsTests.cs | 2 +- .../Extensions/TextColorToTests.cs | 28 +++ .../GravatarImageSourceTests.cs | 6 +- .../Layouts/StateContainerTests.cs | 80 +++++-- .../Mocks/MockDrawingViewHandler.cs | 3 +- .../PopupServiceTests.cs | 138 ++++++++++-- .../Views/DrawingView/DrawingLineTests.cs | 30 ++- .../Views/DrawingView/DrawingViewTests.cs | 30 ++- .../Views/LazyView/LazyViewTests.cs | 36 +++- .../MediaElement/MediaSourceConverterTests.cs | 2 +- .../Views/MediaElement/MediaSourceTests.cs | 2 +- .../Views/Popup/PopupTests.cs | 160 ++++++++++++-- .../Alerts/Snackbar/Snackbar.android.cs | 2 +- .../Alerts/Snackbar/Snackbar.macios.cs | 3 +- .../Alerts/Snackbar/Snackbar.tizen.cs | 1 + .../Animations/BaseAnimation.shared.cs | 3 +- .../Animations/FadeAnimation.shared.cs | 6 +- .../Behaviors/AnimationBehavior.shared.cs | 35 +++- .../Behaviors/MaskedBehavior.shared.cs | 10 +- .../ProgressBarAnimationBehavior.shared.cs | 8 +- .../Validators/ValidationBehavior.shared.cs | 29 +-- .../ColorAnimationExtensions.shared.cs | 9 +- .../GravatarImageSource.shared.cs | 43 ++-- .../StateContainer/StateContainer.shared.cs | 10 +- src/CommunityToolkit.Maui/PopupService.cs | 18 +- .../Views/DrawingView/DrawingView.shared.cs | 12 +- .../Views/LazyView/LazyView.shared.cs | 6 +- .../Views/Popup/Popup.shared.cs | 36 ++-- .../Views/Popup/PopupExtensions.shared.cs | 35 ++-- .../Views/Popup/PopupExtensions.windows.cs | 4 +- 117 files changed, 2077 insertions(+), 735 deletions(-) delete mode 100644 samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/MyLazyView.cs create mode 100644 samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/MyViewLazyView.cs create mode 100644 src/CommunityToolkit.Maui.MediaElement/Interfaces/IAsynchronousMediaElementHandler.cs diff --git a/.editorconfig b/.editorconfig index 6e5bd260ec..8a894f0871 100644 --- a/.editorconfig +++ b/.editorconfig @@ -71,7 +71,7 @@ csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion csharp_style_pattern_matching_over_as_with_null_check = true:suggestion csharp_style_inlined_variable_declaration = true:suggestion csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestions +csharp_style_conditional_delegate_call = true:suggestion # Naming rules @@ -122,6 +122,9 @@ dotnet_diagnostic.CA1050.severity = error # CA2016: Forward the 'cancellationToken' parameter methods that take one dotnet_diagnostic.CA2016.severity = error +# CA1068: CancellationToken parameters must come last +dotnet_diagnostic.CA1068.severity = error + # CA2208: Method passes parameter as the paramName argument to a ArgumentNullException constructor. Replace this argument with one of the method's parameter names. Note that the provided parameter name should have the exact casing as declared on the method. dotnet_diagnostic.CA2208.severity = error diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eae3db0332..92ab2b83bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -125,6 +125,12 @@ Here we will have some: ### Debug Logging * Always use `Trace.WriteLine()` instead of `Debug.WriteLine` for debug logging because `Debug.WriteLine` is removed by the compiler in Release builds +### Methods Returning Task and ValueTask +* Always include a `CancellationToken` as a parameter to every method returning `Task` or `ValueTask` +* If the method is public, provide a the default value for the `CancellationToken` (eg `CancellationToken token = default`) + * If the method is not publc, do not provide a default value for the `CancellationToken` +* Use `CancellationToken.ThrowIfCancellationRequested()` to verify the `CancellationToken` + ### Enums * Always use `Unknown` at index 0 for return types that may have a value that is not known * Always use `Default` at index 0 for option types that can use the system default option diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml.cs index afddaa2b35..a304c4cb54 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml.cs @@ -60,7 +60,8 @@ async void DisplayCustomSnackbarButtonClicked(object? sender, EventArgs args) options, DisplayCustomSnackbarButton); - await customSnackbar.Show(); + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await customSnackbar.Show(cts.Token); DisplayCustomSnackbarButton.Text = dismissCustomSnackbarText; } @@ -68,7 +69,9 @@ async void DisplayCustomSnackbarButtonClicked(object? sender, EventArgs args) { if (customSnackbar is not null) { - await customSnackbar.Dismiss(); + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await customSnackbar.Dismiss(cts.Token); + customSnackbar.Dispose(); } @@ -102,7 +105,7 @@ await Application.Current.MainPage.Navigation.PushModalAsync(new ContentPage Children = { - new Button { Command = new AsyncRelayCommand(() => Snackbar.Make("Snackbar in a Modal Page").Show()) } + new Button { Command = new AsyncRelayCommand(token => Snackbar.Make("Snackbar in a Modal Page").Show(token)) } .Top().CenterHorizontal() .Text("Display Snackbar"), diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/ToastPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/ToastPage.xaml.cs index 875801d27c..4ee35c83af 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/ToastPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Alerts/ToastPage.xaml.cs @@ -16,13 +16,17 @@ public ToastPage(ToastViewModel toastViewModel) : base(toastViewModel) async void ShowToastButtonClicked(object? sender, EventArgs args) { var toast = Toast.Make("This is a default Toast."); - await toast.Show(); + + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await toast.Show(cts.Token); } async void ShowCustomToastButtonClicked(object? sender, EventArgs args) { var toast = Toast.Make("This is a big Toast.", ToastDuration.Long, 30d); - await toast.Show(); + + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await toast.Show(cts.Token); } async void DisplayToastInModalButtonClicked(object? sender, EventArgs e) @@ -37,7 +41,7 @@ await Application.Current.MainPage.Navigation.PushModalAsync(new ContentPage Children = { - new Button { Command = new AsyncRelayCommand(() => Toast.Make("Toast in a Modal Page").Show()) } + new Button { Command = new AsyncRelayCommand(token => Toast.Make("Toast in a Modal Page").Show(token)) } .Top().CenterHorizontal() .Text("Display Toast"), diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml index a835ed6827..5b180cefc5 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml @@ -16,7 +16,7 @@ - + diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml.cs index 785aad33cd..2152a8e920 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/AnimationBehaviorPage.xaml.cs @@ -13,10 +13,10 @@ public AnimationBehaviorPage(AnimationBehaviorViewModel animationBehaviorViewMod class SampleScaleAnimation : BaseAnimation { - public override async Task Animate(VisualElement view) + public override async Task Animate(VisualElement view, CancellationToken token) { - await view.ScaleTo(1.2, Length, Easing); - await view.ScaleTo(1, Length, Easing); + await view.ScaleTo(1.2, Length, Easing).WaitAsync(token); + await view.ScaleTo(1, Length, Easing).WaitAsync(token); } } @@ -24,5 +24,6 @@ class SampleScaleToAnimation : BaseAnimation { public double Scale { get; set; } - public override Task Animate(VisualElement view) => view.ScaleTo(Scale, Length, Easing); + public override Task Animate(VisualElement view, CancellationToken token) + => view.ScaleTo(Scale, Length, Easing).WaitAsync(token); } \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/NumericValidationBehaviorPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/NumericValidationBehaviorPage.xaml.cs index 03aa561cde..6bcf292b81 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/NumericValidationBehaviorPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/NumericValidationBehaviorPage.xaml.cs @@ -16,11 +16,11 @@ async void SetEntryValue(object? sender, EventArgs e) { var toastVisibilityTimeSpan = TimeSpan.FromSeconds(5); var cts = new CancellationTokenSource(toastVisibilityTimeSpan); - + await Toast.Make($"The app will crash because `null` is an invalid value for {nameof(NumericValidationBehavior)}.\nOptionally, {nameof(Options)}.{nameof(Options.SetShouldSuppressExceptionsInBehaviors)} can be set to true", Core.ToastDuration.Long).Show(cts.Token); await Task.Delay(toastVisibilityTimeSpan, cts.Token); - + SafeEntry.Text = null; } } \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/AvatarView/AvatarViewGesturesPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/AvatarView/AvatarViewGesturesPage.xaml.cs index 2148a525cb..f610d8584f 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/AvatarView/AvatarViewGesturesPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/AvatarView/AvatarViewGesturesPage.xaml.cs @@ -7,19 +7,39 @@ public partial class AvatarViewGesturesPage : BasePage InitializeComponent(); - async void DragGestureRecognizer_DragStarting(object sender, DragStartingEventArgs e) => await ShowToastGestureMessage("AvatarView drag gesture recognizer, drag starting."); + async void DragGestureRecognizer_DragStarting(object sender, DragStartingEventArgs e) + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await ShowToastGestureMessage("AvatarView drag gesture recognizer, drag starting.", cts.Token); + } - async void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e) => await ShowToastGestureMessage("AvatarView pan gesture recognizer, pan updated."); + async void PanGestureRecognizer_PanUpdated(object sender, PanUpdatedEventArgs e) + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await ShowToastGestureMessage("AvatarView pan gesture recognizer, pan updated.", cts.Token); + } - async void PinchGestureRecognizer_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e) => await ShowToastGestureMessage("AvatarView pinch gesture recognizer, pinch updated."); + async void PinchGestureRecognizer_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e) + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await ShowToastGestureMessage("AvatarView pinch gesture recognizer, pinch updated.", cts.Token); + } - async void SwipeGestureRecognizer_Swiped(object sender, SwipedEventArgs e) => await ShowToastGestureMessage("AvatarView swipe gesture recognizer, swiped."); + async void SwipeGestureRecognizer_Swiped(object sender, SwipedEventArgs e) + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await ShowToastGestureMessage("AvatarView swipe gesture recognizer, swiped.", cts.Token); + } - async void TapGestureRecognizer_Tapped(object sender, EventArgs e) => await ShowToastGestureMessage("AvatarView Tap Gesture Recognizer, tapped."); + async void TapGestureRecognizer_Tapped(object sender, EventArgs e) + { + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await ShowToastGestureMessage("AvatarView Tap Gesture Recognizer, tapped.", cts.Token); + } - static async Task ShowToastGestureMessage(string message) + static Task ShowToastGestureMessage(string message, CancellationToken token) { Core.IToast toast = Toast.Make(message, Core.ToastDuration.Short); - await toast.Show(); + return toast.Show(token); } } \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/DrawingViewPage.xaml.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/DrawingViewPage.xaml.cs index 1421e92598..1dfdf1d52e 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/DrawingViewPage.xaml.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/DrawingViewPage.xaml.cs @@ -30,23 +30,29 @@ void LoadPointsButtonClicked(object sender, EventArgs e) async void GetCurrentDrawingViewImageClicked(object sender, EventArgs e) { - var stream = await DrawingViewControl.GetImageStream(GestureImage.Width, GestureImage.Height); + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var stream = await DrawingViewControl.GetImageStream(GestureImage.Width, GestureImage.Height, cts.Token); + GestureImage.Source = ImageSource.FromStream(() => stream); } async void GenerateImageButtonClicked(object sender, EventArgs e) { var lines = GenerateLines(2); - await DrawImage(lines); + + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await DrawImage(lines, cts.Token); } - async Task DrawImage(IEnumerable lines) + async Task DrawImage(IEnumerable lines, CancellationToken token) { var drawingLines = lines.ToList(); var points = drawingLines.SelectMany(x => x.Points).ToList(); var stream = await DrawingView.GetImageStream(drawingLines, new Size(points.Max(x => x.X) - points.Min(x => x.X), points.Max(x => x.Y) - points.Min(x => x.Y)), - Colors.Gray); + Colors.Gray, + token); + GestureImage.Source = ImageSource.FromStream(() => stream); } @@ -71,7 +77,10 @@ async void OnDrawingLineCompleted(object sender, DrawingLineCompletedEventArgs e { var width = GetSide(GestureImage.Width); var height = GetSide(GestureImage.Height); - var stream = await e.LastDrawingLine.GetImageStream(width, height, Colors.Gray.AsPaint()); + + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var stream = await e.LastDrawingLine.GetImageStream(width, height, Colors.Gray.AsPaint(), cts.Token); + GestureImage.Source = ImageSource.FromStream(() => stream); } } \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/CustomLazyView.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/CustomLazyView.cs index fb995626aa..2a2fa8c2bb 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/CustomLazyView.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/CustomLazyView.cs @@ -4,13 +4,13 @@ namespace CommunityToolkit.Maui.Sample.Pages.Views.LazyView; public class CustomLazyView : Maui.Views.LazyView where TView : View, new() { - public override async ValueTask LoadViewAsync() + public override async ValueTask LoadViewAsync(CancellationToken token) { // display a loading indicator Content = new ActivityIndicator { IsRunning = true }.Center(); // simulate a long running task - await Task.Delay(3000); + await Task.Delay(3000, token); // load the view Content = new TView { BindingContext = BindingContext }; diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/LazyViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/LazyViewPage.xaml index 1d1987bffa..4a1060b548 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/LazyViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/LazyView/LazyViewPage.xaml @@ -54,7 +54,7 @@