Explorar o código

Update preloading logic

Ruben hai 1 ano
pai
achega
9a2fc1889b

+ 3 - 28
src/PicView.WPF/ChangeImage/FastPic.cs

@@ -15,29 +15,6 @@ internal static class FastPic
     private static bool _updateSource;
 
     internal static async Task Run(int index)
-    {
-        using var cts = new CancellationTokenSource();
-        var cancelToken = cts.Token;
-        try
-        {
-            await Run(index, cancelToken).ConfigureAwait(false);
-        }
-        catch (OperationCanceledException)
-        {
-#if DEBUG
-            Trace.WriteLine($"{nameof(Run)} cancelled:\n");
-#endif
-        }
-        catch (Exception ex)
-        {
-#if DEBUG
-            Trace.WriteLine($"{nameof(Run)} exception:\n{ex.Message}");
-#endif
-            Tooltip.ShowTooltipMessage(ex.Message, true, TimeSpan.FromSeconds(5));
-        }
-    }
-
-    private static async Task Run(int index, CancellationToken cancellationToken)
     {
         if (_timer is null)
         {
@@ -71,7 +48,7 @@ internal static class FastPic
                     showThumb = false;
                 }
 
-                await Task.Delay(10, cancellationToken);
+                await Task.Delay(10);
             }
         }
         else
@@ -95,7 +72,7 @@ internal static class FastPic
             }
         }
 
-        await UpdateImage.UpdateImageValuesAsync(index, preLoadValue, cancellationToken, true).ConfigureAwait(false);
+        await UpdateImage.UpdateImageValuesAsync(index, preLoadValue, true).ConfigureAwait(false);
 
         _updateSource = false;
         await PreLoader.PreLoadAsync(index, Pics.Count).ConfigureAwait(false);
@@ -140,11 +117,9 @@ internal static class FastPic
         {
             await Task.Delay(10).ConfigureAwait(false);
         }
-        using var cts = new CancellationTokenSource();
-        var cancelToken = cts.Token;
         try
         {
-            await UpdateImage.UpdateImageValuesAsync(FolderIndex, preLoadValue, cancelToken).ConfigureAwait(false);
+            await UpdateImage.UpdateImageValuesAsync(FolderIndex, preLoadValue).ConfigureAwait(false);
         }
         catch (OperationCanceledException)
         {

+ 36 - 53
src/PicView.WPF/ChangeImage/LoadPic.cs

@@ -428,7 +428,7 @@ internal static class LoadPic
     /// </summary>
     /// <param name="index">The index of the image to load.</param>
     /// <param name="fileInfo">The file information for the image. If not specified, the file information will be obtained from the image list using the specified index.</param>
-    internal static async Task LoadPicAtIndexAsync(int index, FileInfo? fileInfo = null)
+    internal static async Task LoadPicAtIndexAsync(int index, FileInfo? fileInfo = null) => await Task.Run(async () =>
     {
         if (index < 0 || index >= Pics.Count)
         {
@@ -436,31 +436,23 @@ internal static class LoadPic
         }
 
         FolderIndex = index;
-        using var cts = new CancellationTokenSource();
-        var cancelToken = cts.Token;
-        try
-        {
-            await LoadPicAtIndexAsync(index, cancelToken, fileInfo);
-        }
-        catch (TaskCanceledException)
-        {
-#if DEBUG
-            Trace.WriteLine($"{nameof(LoadPicAtIndexAsync)} cancelled");
-#endif
-        }
-        catch (Exception ex)
+        var preLoadValue = PreLoader.Get(index);
+        fileInfo ??= preLoadValue?.FileInfo;
+        if (fileInfo == null)
         {
+            try
+            {
+                fileInfo = new FileInfo(Pics[index]);
+            }
+            catch (Exception ex)
+            {
 #if DEBUG
-            Trace.WriteLine($"{nameof(LoadPicAtIndexAsync)} exception:\n{ex.Message}");
+                Trace.WriteLine($"{nameof(LoadPicAtIndexAsync)} {index} exception:\n{ex.Message}");
 #endif
-            Tooltip.ShowTooltipMessage(ex.Message, true, TimeSpan.FromSeconds(5));
+                Tooltip.ShowTooltipMessage(ex.Message, true, TimeSpan.FromSeconds(5));
+                return;
+            }
         }
-    }
-
-    private static async Task LoadPicAtIndexAsync(int index, CancellationToken cancellationToken, FileInfo? fileInfo = null) => await Task.Run(async () =>
-    {
-        var preLoadValue = PreLoader.Get(index);
-        fileInfo ??= preLoadValue?.FileInfo ?? new FileInfo(Pics[index]);
 
         if (!fileInfo.Exists)
         {
@@ -473,7 +465,7 @@ internal static class LoadPic
             {
                 var next = ImageIteration.GetNextIndex(Reverse ? NavigateTo.Previous : NavigateTo.Next,
                     SettingsHelper.Settings.UIProperties.Looping, Pics, index);
-                await LoadPicAtIndexAsync(next, cancellationToken);
+                await LoadPicAtIndexAsync(next);
                 return;
             }
         }
@@ -485,37 +477,47 @@ internal static class LoadPic
             {
                 if (showThumb)
                 {
-                    await SetThumb();
+                    LoadingPreview(fileInfo);
                     showThumb = false;
                 }
 
-                await Task.Delay(50, cancellationToken);
+                await Task.Delay(50);
                 if (FolderIndex != index)
                 {
                     // Skip loading if user went to next value
-                    throw new TaskCanceledException();
+                    return;
                 }
             }
         }
         else
         {
-            await SetThumb();
-            await PreLoader.AddAsync(index, fileInfo).ConfigureAwait(false);
+            LoadingPreview(fileInfo);
+            _ = Task.Run(() => PreLoader.AddAsync(index, fileInfo));
+            do
+            {
+                preLoadValue = PreLoader.Get(index);
+                await Task.Delay(50);
+                if (index != FolderIndex)
+                {
+                    // Skip loading if user went to next value
+                    return;
+                }
+            } while (preLoadValue is null || preLoadValue.IsLoading);
+            //await PreLoader.AddAsync(index, fileInfo).ConfigureAwait(false);
             if (index != FolderIndex)
             {
                 // Skip loading if user went to next value
-                throw new TaskCanceledException();
+                return;
             }
-            preLoadValue = PreLoader.Get(index);
         }
 
         if (FolderIndex != index)
         {
             // Skip loading if user went to next value
-            throw new TaskCanceledException();
+            return;
         }
 
-        await UpdateImage.UpdateImageValuesAsync(index, preLoadValue, cancellationToken);
+        await UpdateImage.UpdateImageValuesAsync(index, preLoadValue);
 
         if (ConfigureWindows.GetImageInfoWindow is { IsVisible: true })
             await ImageInfo.UpdateValuesAsync(preLoadValue?.FileInfo).ConfigureAwait(false);
@@ -532,26 +534,7 @@ internal static class LoadPic
         {
             FileHistoryNavigation.Add(Pics[index]);
         }
-        return;
-
-        async Task SetThumb()
-        {
-            var thumb = Thumbnails.GetThumb(index, fileInfo);
-            if (thumb.HasValue)
-            {
-                await ConfigureWindows.GetMainWindow?.Dispatcher?.InvokeAsync(() =>
-                {
-                    if (index != FolderIndex)
-                        return;
-                    ConfigureWindows.GetMainWindow.MainImage.Source = thumb.Value.BitmapSource;
-                    if (thumb.Value is { OriginalWidth: not null, OriginalHeight: not null })
-                    {
-                        ScaleImage.FitImage(thumb.Value.OriginalWidth.Value, thumb.Value.OriginalHeight.Value);
-                    }
-                }, DispatcherPriority.Normal, cancellationToken);
-            }
-        }
-    }, cancellationToken);
+    });
 
     #endregion Load Pic at Index
 
@@ -582,7 +565,7 @@ internal static class LoadPic
             }
 
             ConfigureWindows.GetMainWindow.MainImage.Source = thumb.Value.BitmapSource;
-            if (thumb.Value.OriginalWidth.HasValue && thumb.Value.OriginalHeight.HasValue)
+            if (thumb.Value is { OriginalWidth: not null, OriginalHeight: not null })
             {
                 ScaleImage.FitImage(thumb.Value.OriginalWidth.Value, thumb.Value.OriginalHeight.Value);
             }

+ 38 - 6
src/PicView.WPF/ChangeImage/PreLoader.cs

@@ -86,7 +86,7 @@ internal static class PreLoader
 #if DEBUG
 
     // ReSharper disable once ConvertToConstant.Local
-    private static readonly bool ShowAddRemove = false;
+    private static readonly bool ShowAddRemove = true;
 
 #endif
 
@@ -267,16 +267,21 @@ internal static class PreLoader
             return;
         }
         _isRunning = true;
-        int prevStartingIndex;
-        using var cancellationTokenSource = new CancellationTokenSource();
-        var nextStartingIndex = currentIndex;
+        int nextStartingIndex, prevStartingIndex, deleteIndex;
+        var cancellationTokenSource = new CancellationTokenSource();
         if (Reverse)
         {
-            prevStartingIndex = currentIndex - 1;
+            nextStartingIndex = currentIndex + NegativeIterations > count
+                ? count
+                : currentIndex + NegativeIterations;
+            prevStartingIndex = currentIndex + 1;
+            deleteIndex = prevStartingIndex + NegativeIterations;
         }
         else
         {
-            prevStartingIndex = currentIndex + 1;
+            nextStartingIndex = currentIndex - NegativeIterations < 0 ? 0 : currentIndex - NegativeIterations;
+            prevStartingIndex = currentIndex - 1;
+            deleteIndex = prevStartingIndex - NegativeIterations;
         }
 
 #if DEBUG
@@ -284,6 +289,7 @@ internal static class PreLoader
             Trace.WriteLine($"\nPreLoading started at {nextStartingIndex}\n");
 #endif
 
+        var array = new int[MaxCount];
         ParallelOptions options = new()
         {
             MaxDegreeOfParallelism = Environment.ProcessorCount - 2 < 1 ? 1 : Environment.ProcessorCount - 2
@@ -318,6 +324,32 @@ internal static class PreLoader
             return;
         }
 
+        for (var i = 0; i < NegativeIterations; i++)
+        {
+            try
+            {
+                if (Pics.Count == 0 || count != Pics.Count)
+                {
+                    throw new TaskCanceledException();
+                }
+            }
+            catch (Exception)
+            {
+                return;
+            }
+
+            int index;
+            if (Reverse)
+            {
+                index = (deleteIndex + i) % Pics.Count;
+            }
+            else
+            {
+                index = (deleteIndex - i + Pics.Count) % Pics.Count;
+            }
+
+            Remove(index);
+        }
         while (PreLoadList.Count > MaxCount)
         {
             Remove(Reverse ? PreLoadList.Keys.Max() : PreLoadList.Keys.Min());

+ 5 - 5
src/PicView.WPF/ChangeImage/UpdateImage.cs

@@ -31,7 +31,7 @@ internal static class UpdateImage
     /// <param name="cancellationToken">The cancellation token.</param>
     /// <param name="fastPic">Use different loading when key held down.</param>
     /// <returns>A task representing the asynchronous operation.</returns>
-    internal static async Task UpdateImageValuesAsync(int index, PreLoader.PreLoadValue preLoadValue, CancellationToken cancellationToken, bool fastPic = false)
+    internal static async Task UpdateImageValuesAsync(int index, PreLoader.PreLoadValue preLoadValue, bool fastPic = false)
     {
         if (preLoadValue is null)
         {
@@ -44,7 +44,7 @@ internal static class UpdateImage
             while (preLoadValue.IsLoading) // Fix rare occurrences of non-loaded image
             {
                 x++;
-                await Task.Delay(50, cancellationToken);
+                await Task.Delay(50);
                 if (index != FolderIndex)
                 {
                     return;
@@ -85,7 +85,7 @@ internal static class UpdateImage
             {
                 ZoomLogic.ResetZoom(false);
             }
-        }, DispatcherPriority.Send, cancellationToken);
+        }, DispatcherPriority.Send);
 
         if (index != FolderIndex || preLoadValue.BitmapSource is null)
         {
@@ -130,7 +130,7 @@ internal static class UpdateImage
             {
                 GetSpinWaiter.Visibility = Visibility.Collapsed;
             }
-        }, DispatcherPriority.Send, cancellationToken);
+        }, DispatcherPriority.Send);
 
         preLoadValue.FileInfo ??= new FileInfo(Pics[FolderIndex]);
         if (preLoadValue.FileInfo.Extension.Equals(".gif", StringComparison.OrdinalIgnoreCase))
@@ -148,7 +148,7 @@ internal static class UpdateImage
                     }
 
                     AnimationBehavior.SetSourceUri(ConfigureWindows.GetMainWindow.MainImage, uri);
-                }, DispatcherPriority.Normal, cancellationToken);
+                }, DispatcherPriority.Normal);
             }
         }