diff --git a/MapControl/UWP/Tile.UWP.cs b/MapControl/UWP/Tile.UWP.cs index 58337673..55ee8f24 100644 --- a/MapControl/UWP/Tile.UWP.cs +++ b/MapControl/UWP/Tile.UWP.cs @@ -3,12 +3,15 @@ // Licensed under the Microsoft Public License (Ms-PL) using System; +using System.Threading.Tasks; #if WINUI +using Microsoft.System; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Media.Imaging; #else +using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; @@ -19,6 +22,35 @@ namespace MapControl { public partial class Tile { + public async Task SetImageAsync(Func> loadImageFunc) + { + var tcs = new TaskCompletionSource(); + + async void callback() + { + try + { + SetImage(await loadImageFunc()); + tcs.SetResult(null); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + } +#if WINUI + if (!Image.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, callback)) + { + // should never happen, but just in case: reset Pending state and complete TaskCompletionSource + Pending = true; + tcs.SetResult(null); + } +#else + _ = Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, callback); +#endif + _ = await tcs.Task.ConfigureAwait(false); // wait until image loading in UI thread is completed + } + public void SetImage(ImageSource image, bool fadeIn = true) { Pending = false; diff --git a/MapControl/UWP/TileImageLoader.UWP.cs b/MapControl/UWP/TileImageLoader.UWP.cs index 6e87189f..281d67b5 100644 --- a/MapControl/UWP/TileImageLoader.UWP.cs +++ b/MapControl/UWP/TileImageLoader.UWP.cs @@ -6,13 +6,6 @@ using System; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using Windows.Storage; -#if WINUI -using Microsoft.System; -using Microsoft.UI.Xaml.Media; -#else -using Windows.UI.Core; -using Windows.UI.Xaml.Media; -#endif namespace MapControl { @@ -52,42 +45,13 @@ namespace MapControl if (buffer != null && buffer.Length > 0) { - await SetTileImageAsync(tile, () => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); + await tile.SetImageAsync(() => ImageLoader.LoadImageAsync(buffer)).ConfigureAwait(false); } } private static Task LoadTileAsync(Tile tile, TileSource tileSource) { - return SetTileImageAsync(tile, () => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); - } - - private static async Task SetTileImageAsync(Tile tile, Func> loadImage) - { - var tcs = new TaskCompletionSource(); - - async void callback() - { - try - { - tile.SetImage(await loadImage()); - tcs.SetResult(null); - } - catch (Exception ex) - { - tcs.SetException(ex); - } - } -#if WINUI - if (!tile.Image.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, callback)) - { - // not sure if this can ever happen, but just in case: reset tile.Pending and complete tcs - tile.Pending = true; - tcs.SetResult(null); - } -#else - _ = tile.Image.Dispatcher.RunAsync(CoreDispatcherPriority.Low, callback); -#endif - _ = await tcs.Task.ConfigureAwait(false); // wait until image loading in the UI thread is completed + return tile.SetImageAsync(() => tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel)); } } } diff --git a/MapControl/WPF/Tile.WPF.cs b/MapControl/WPF/Tile.WPF.cs index c75fd132..6976433a 100644 --- a/MapControl/WPF/Tile.WPF.cs +++ b/MapControl/WPF/Tile.WPF.cs @@ -6,11 +6,17 @@ using System; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Windows.Threading; namespace MapControl { public partial class Tile { + public DispatcherOperation SetImageAsync(ImageSource image) + { + return Image.Dispatcher.InvokeAsync(() => SetImage(image)); + } + public void SetImage(ImageSource image, bool fadeIn = true) { Pending = false; diff --git a/MapControl/WPF/TileImageLoader.WPF.cs b/MapControl/WPF/TileImageLoader.WPF.cs index 054ddff6..241aa3fb 100644 --- a/MapControl/WPF/TileImageLoader.WPF.cs +++ b/MapControl/WPF/TileImageLoader.WPF.cs @@ -58,7 +58,7 @@ namespace MapControl { var image = await ImageLoader.LoadImageAsync(buffer).ConfigureAwait(false); - await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image)); + await tile.SetImageAsync(image); } } @@ -66,7 +66,7 @@ namespace MapControl { var image = await tileSource.LoadImageAsync(tile.XIndex, tile.Y, tile.ZoomLevel).ConfigureAwait(false); - await tile.Image.Dispatcher.InvokeAsync(() => tile.SetImage(image)); + await tile.SetImageAsync(image); } private static Task GetCacheAsync(string cacheKey)