From d4e851e0f74adde325cc4b6979797af08b4c60e5 Mon Sep 17 00:00:00 2001 From: Clemens Date: Mon, 22 Nov 2021 23:07:07 +0100 Subject: [PATCH] Refactored TileImageLoader --- MapControl/Shared/TileImageLoader.cs | 30 ++++++++++++++--------- MapControl/UWP/TileImageLoader.UWP.cs | 10 ++++---- MapControl/WPF/TileImageLoader.WPF.cs | 4 +-- MapControl/WinUI/TileImageLoader.WinUI.cs | 10 ++++---- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/MapControl/Shared/TileImageLoader.cs b/MapControl/Shared/TileImageLoader.cs index 779eb618..25b6b2f5 100644 --- a/MapControl/Shared/TileImageLoader.cs +++ b/MapControl/Shared/TileImageLoader.cs @@ -49,13 +49,20 @@ namespace MapControl /// public Task LoadTiles(IEnumerable tiles, TileSource tileSource, string cacheName) { - pendingTiles?.Clear(); // stop download from current stack - - pendingTiles = new ConcurrentStack(tiles.Where(tile => tile.Pending).Reverse()); + pendingTiles?.Clear(); // stop processing the current queue TileSource = tileSource; - if (tileSource == null || pendingTiles.IsEmpty) + if (tileSource == null) + { + return Task.CompletedTask; + } + + pendingTiles = new ConcurrentStack(tiles.Where(tile => tile.Pending).Reverse()); + + var numTasks = Math.Min(pendingTiles.Count, MaxLoadTasks); + + if (numTasks < 1) { return Task.CompletedTask; } @@ -65,14 +72,13 @@ namespace MapControl cacheName = null; // no tile caching } - var tasks = Enumerable - .Range(0, Math.Min(pendingTiles.Count, MaxLoadTasks)) - .Select(_ => Task.Run(() => LoadPendingTilesAsync(pendingTiles, tileSource, cacheName))); + var tasks = Enumerable.Range(0, numTasks) + .Select(_ => Task.Run(() => LoadPendingTiles(pendingTiles, tileSource, cacheName))); return Task.WhenAll(tasks); } - private static async Task LoadPendingTilesAsync(ConcurrentStack pendingTiles, TileSource tileSource, string cacheName) + private static async Task LoadPendingTiles(ConcurrentStack pendingTiles, TileSource tileSource, string cacheName) { while (pendingTiles.TryPop(out var tile)) { @@ -80,7 +86,7 @@ namespace MapControl try { - await LoadTileAsync(tile, tileSource, cacheName).ConfigureAwait(false); + await LoadTile(tile, tileSource, cacheName).ConfigureAwait(false); } catch (Exception ex) { @@ -89,11 +95,11 @@ namespace MapControl } } - private static Task LoadTileAsync(Tile tile, TileSource tileSource, string cacheName) + private static Task LoadTile(Tile tile, TileSource tileSource, string cacheName) { if (string.IsNullOrEmpty(cacheName)) { - return LoadTileAsync(tile, tileSource); + return LoadTile(tile, tileSource); } var uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel); @@ -113,7 +119,7 @@ namespace MapControl var cacheKey = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}{4}", cacheName, tile.ZoomLevel, tile.XIndex, tile.Y, extension); - return LoadCachedTileAsync(tile, uri, cacheKey); + return LoadCachedTile(tile, uri, cacheKey); } private static DateTime GetExpiration(TimeSpan? maxAge) diff --git a/MapControl/UWP/TileImageLoader.UWP.cs b/MapControl/UWP/TileImageLoader.UWP.cs index 183f3036..ff229f15 100644 --- a/MapControl/UWP/TileImageLoader.UWP.cs +++ b/MapControl/UWP/TileImageLoader.UWP.cs @@ -36,7 +36,7 @@ namespace MapControl public static Caching.IImageCache Cache { get; set; } - private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey) + private static async Task LoadCachedTile(Tile tile, Uri uri, string cacheKey) { var cacheItem = await Cache.GetAsync(cacheKey).ConfigureAwait(false); var buffer = cacheItem?.Item1; @@ -56,16 +56,16 @@ namespace MapControl if (buffer != null && buffer.Length > 0) { - await SetTileImageAsync(tile, () => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); + await SetTileImage(tile, () => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); } } - private static Task LoadTileAsync(Tile tile, TileSource tileSource) + private static Task LoadTile(Tile tile, TileSource tileSource) { - return SetTileImageAsync(tile, () => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); + return SetTileImage(tile, () => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); } - public static async Task SetTileImageAsync(Tile tile, Func> loadImageFunc) + private static async Task SetTileImage(Tile tile, Func> loadImageFunc) { var tcs = new TaskCompletionSource(); diff --git a/MapControl/WPF/TileImageLoader.WPF.cs b/MapControl/WPF/TileImageLoader.WPF.cs index 368d417d..f7b55bf7 100644 --- a/MapControl/WPF/TileImageLoader.WPF.cs +++ b/MapControl/WPF/TileImageLoader.WPF.cs @@ -25,7 +25,7 @@ namespace MapControl public static ObjectCache Cache { get; set; } = MemoryCache.Default; - private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey) + private static async Task LoadCachedTile(Tile tile, Uri uri, string cacheKey) { var cacheItem = Cache.Get(cacheKey) as Tuple; var buffer = cacheItem?.Item1; @@ -53,7 +53,7 @@ namespace MapControl } } - private static async Task LoadTileAsync(Tile tile, TileSource tileSource) + private static async Task LoadTile(Tile tile, TileSource tileSource) { var image = await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel).ConfigureAwait(false); diff --git a/MapControl/WinUI/TileImageLoader.WinUI.cs b/MapControl/WinUI/TileImageLoader.WinUI.cs index 8f998f5f..4ec94e3e 100644 --- a/MapControl/WinUI/TileImageLoader.WinUI.cs +++ b/MapControl/WinUI/TileImageLoader.WinUI.cs @@ -36,7 +36,7 @@ namespace MapControl public static Caching.IImageCache Cache { get; set; } - private static async Task LoadCachedTileAsync(Tile tile, Uri uri, string cacheKey) + private static async Task LoadCachedTile(Tile tile, Uri uri, string cacheKey) { var cacheItem = await Cache.GetAsync(cacheKey).ConfigureAwait(false); var buffer = cacheItem?.Item1; @@ -56,16 +56,16 @@ namespace MapControl if (buffer != null && buffer.Length > 0) { - await SetTileImageAsync(tile, () => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); + await SetTileImage(tile, () => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); } } - private static Task LoadTileAsync(Tile tile, TileSource tileSource) + private static Task LoadTile(Tile tile, TileSource tileSource) { - return SetTileImageAsync(tile, () => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); + return SetTileImage(tile, () => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); } - public static Task SetTileImageAsync(Tile tile, Func> loadImageFunc) + private static Task SetTileImage(Tile tile, Func> loadImageFunc) { var tcs = new TaskCompletionSource();