Added Tile.SetImageAsync

This commit is contained in:
Clemens 2021-06-27 21:50:13 +02:00
parent 772549c109
commit 9ebc88204b
4 changed files with 42 additions and 40 deletions

View file

@ -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<Task<ImageSource>> loadImageFunc)
{
var tcs = new TaskCompletionSource<object>();
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;

View file

@ -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<Task<ImageSource>> loadImage)
{
var tcs = new TaskCompletionSource<object>();
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));
}
}
}

View file

@ -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;

View file

@ -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<ImageCacheItem> GetCacheAsync(string cacheKey)