فهرست منبع

Update cancellation support

Ruben 9 ماه پیش
والد
کامیت
706818ce5f

+ 16 - 10
src/PicView.Avalonia/Navigation/ImageIterator.cs

@@ -442,7 +442,7 @@ public sealed class ImageIterator : IDisposable
         return next;
     }
 
-    public async Task NextIteration(NavigateTo navigateTo)
+    public async Task NextIteration(NavigateTo navigateTo, CancellationToken cancellationToken = default)
     {
         var index = GetIteration(CurrentIndex, navigateTo, SettingsHelper.Settings.ImageScaling.ShowImageSideBySide);
         if (index < 0)
@@ -452,11 +452,11 @@ public sealed class ImageIterator : IDisposable
 
         if (!MainKeyboardShortcuts.IsKeyHeldDown)
         {
-            await IterateToIndex(index);
+            await IterateToIndex(index, cancellationToken).ConfigureAwait(false);
         }
         else
         {
-            await TimerIteration(index);
+            await TimerIteration(index).ConfigureAwait(false);
         }
     }
     
@@ -472,16 +472,15 @@ public sealed class ImageIterator : IDisposable
         await IterateToIndex(index).ConfigureAwait(false);
     }
 
-    public async Task IterateToIndex(int index)
+    public async Task IterateToIndex(int index, CancellationToken cancellationToken = default)
     {
-        SetTitleHelper.SetLoadingTitle(_vm);
-        
         if (index < 0 || index >= ImagePaths.Count)
         {
             ErrorHandling.ShowStartUpMenu(_vm);
             return;
         }
         
+        using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
         // UI is more responsive when started in new thread
         await Task.Run(async () =>
         {
@@ -500,10 +499,11 @@ public sealed class ImageIterator : IDisposable
 
                     while (preloadValue.IsLoading)
                     {
-                        await Task.Delay(20).ConfigureAwait(false);
+                        await Task.Delay(20, cancellationToken).ConfigureAwait(false);
                         if (CurrentIndex != index)
                         {
                             // Skip loading if user went to next value
+                            await cts.CancelAsync();
                             return;
                         }
                     }
@@ -517,6 +517,7 @@ public sealed class ImageIterator : IDisposable
                 if (CurrentIndex != index)
                 {
                     // Skip loading if user went to next value
+                    await cts.CancelAsync();
                     return;
                 }
 
@@ -527,6 +528,7 @@ public sealed class ImageIterator : IDisposable
                     if (CurrentIndex != index)
                     {
                         // Skip loading if user went to next value
+                        await cts.CancelAsync();
                         return;
                     }
 
@@ -534,11 +536,13 @@ public sealed class ImageIterator : IDisposable
                     {
                         _vm.SecondaryImageSource = nextPreloadValue.ImageModel?.Image;
                     }
+                    cancellationToken.ThrowIfCancellationRequested();
                     await UpdateImage.UpdateSource(_vm, index, ImagePaths, IsReversed, preloadValue, nextPreloadValue)
                         .ConfigureAwait(false);
                 }
                 else
                 {
+                    cancellationToken.ThrowIfCancellationRequested();
                     await UpdateImage.UpdateSource(_vm, index, ImagePaths, IsReversed, preloadValue)
                         .ConfigureAwait(false);
                 }
@@ -553,7 +557,7 @@ public sealed class ImageIterator : IDisposable
                         });
                     }
 
-                    await PreLoader.PreLoadAsync(CurrentIndex, ImagePaths.Count, IsReversed, ImagePaths)
+                    await PreLoader.PreLoadAsync(CurrentIndex, ImagePaths.Count, IsReversed, ImagePaths, cancellationToken)
                         .ConfigureAwait(false);
                 }
 
@@ -581,6 +585,8 @@ public sealed class ImageIterator : IDisposable
 
             void TryShowPreview(PreLoadValue preloadValue)
             {
+                SetTitleHelper.SetLoadingTitle(_vm);
+                
                 if (preloadValue is null)
                 {
                     return;
@@ -600,7 +606,7 @@ public sealed class ImageIterator : IDisposable
                 _vm.ImageSource = null;
                 _vm.SecondaryImageSource = null;
             }
-        });
+        }, cancellationToken);
     }
 
     private static Timer? _timer;
@@ -627,7 +633,7 @@ public sealed class ImageIterator : IDisposable
 
         _timer.Interval = TimeSpan.FromSeconds(SettingsHelper.Settings.UIProperties.NavSpeed).TotalMilliseconds;
         _timer.Start();
-        await IterateToIndex(index);
+        await IterateToIndex(index).ConfigureAwait(false);
     }
 
     public void UpdateFileListAndIndex(List<string> fileList, int index)

+ 32 - 1
src/PicView.Avalonia/Navigation/NavigationHelper.cs

@@ -24,6 +24,7 @@ namespace PicView.Avalonia.Navigation;
 /// </summary>
 public static class NavigationHelper
 {
+    private static CancellationTokenSource? _cancellationTokenSource;
 
     #region Navigation
     
@@ -59,7 +60,8 @@ public static class NavigationHelper
         else
         {
             var navigateTo = next ? NavigateTo.Next : NavigateTo.Previous;
-            await vm.ImageIterator.NextIteration(navigateTo).ConfigureAwait(false);
+            _cancellationTokenSource = new CancellationTokenSource();
+            await vm.ImageIterator.NextIteration(navigateTo, _cancellationTokenSource.Token).ConfigureAwait(false);
         }
     }
 
@@ -147,6 +149,10 @@ public static class NavigationHelper
             return;
         }
         SetTitleHelper.SetLoadingTitle(vm);
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
         var fileList = await GetNextFolderFileList(next, vm).ConfigureAwait(false);
 
         if (fileList is null)
@@ -180,6 +186,11 @@ public static class NavigationHelper
         UIHelper.CloseMenus(vm);
         vm.IsLoading = true;
         SetTitleHelper.SetLoadingTitle(vm);
+        
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
 
         // Starting in new task makes it more responsive and works better
         await Task.Run(async () =>
@@ -263,6 +274,11 @@ public static class NavigationHelper
         {
             vm.PlatformService.StopTaskbarProgress();
         }
+        
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
 
         if (vm.ImageIterator is not null)
         {
@@ -313,6 +329,11 @@ public static class NavigationHelper
     /// </returns>
     public static async Task LoadPicFromArchiveAsync(string path, MainViewModel vm)
     {
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
+        
         var extraction = await ArchiveExtraction.ExtractArchiveAsync(path, vm.PlatformService.ExtractWithLocalSoftwareAsync).ConfigureAwait(false);
         if (!extraction)
         {
@@ -349,6 +370,11 @@ public static class NavigationHelper
     /// <returns>A task representing the asynchronous operation.</returns>
     public static async Task LoadPicFromUrlAsync(string url, MainViewModel vm)
     {
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
+        
         string destination;
 
         try
@@ -466,6 +492,11 @@ public static class NavigationHelper
         vm.IsLoading = true;
         SetTitleHelper.SetLoadingTitle(vm);
         
+        if (_cancellationTokenSource is not null)
+        {
+            await _cancellationTokenSource.CancelAsync();
+        }
+        
         if (SettingsHelper.Settings.UIProperties.IsTaskbarProgressEnabled)
         {
             vm.PlatformService.StopTaskbarProgress();

+ 8 - 4
src/PicView.Avalonia/Views/ImageViewer.axaml.cs

@@ -14,7 +14,6 @@ using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageTransformations;
-using PicView.Core.Navigation;
 using Point = Avalonia.Point;
 
 namespace PicView.Avalonia.Views;
@@ -185,13 +184,18 @@ public partial class ImageViewer : UserControl
             {
                 return;
             }
-            var navigateTo = SettingsHelper.Settings.Zoom.HorizontalReverseScroll ? NavigateTo.Previous : NavigateTo.Next;
+
+            bool next;
             if (reverse)
             {
-                navigateTo = SettingsHelper.Settings.Zoom.HorizontalReverseScroll ? NavigateTo.Next : NavigateTo.Previous;
+                next = SettingsHelper.Settings.Zoom.HorizontalReverseScroll;
+            }
+            else
+            {
+                next = !SettingsHelper.Settings.Zoom.HorizontalReverseScroll;
             }
 
-            await mainViewModel.ImageIterator.NextIteration(navigateTo).ConfigureAwait(false);
+            await NavigationHelper.Navigate(next, mainViewModel).ConfigureAwait(false);
         }
     }