Replaced internal HttpResponse class by tuple

This commit is contained in:
ClemensFischer 2025-09-10 23:10:32 +02:00
parent d6faf252ee
commit ea46224c14
2 changed files with 51 additions and 70 deletions

View file

@ -49,11 +49,11 @@ namespace MapControl
{ {
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{ {
var response = await GetHttpResponseAsync(uri, progress); (var buffer, var _) = await GetHttpResponseAsync(uri, progress);
if (response?.Buffer != null) if (buffer != null)
{ {
image = await LoadImageAsync(response.Buffer); image = await LoadImageAsync(buffer);
} }
} }
else if (uri.IsFile || !uri.IsAbsoluteUri) else if (uri.IsFile || !uri.IsAbsoluteUri)
@ -75,21 +75,10 @@ namespace MapControl
return image; return image;
} }
internal class HttpResponse internal static async Task<(byte[], TimeSpan?)> GetHttpResponseAsync(Uri uri, IProgress<double> progress = null)
{ {
public byte[] Buffer { get; } byte[] buffer = null;
public TimeSpan? MaxAge { get; } TimeSpan? maxAge = null;
public HttpResponse(byte[] buffer, TimeSpan? maxAge)
{
Buffer = buffer;
MaxAge = maxAge;
}
}
internal static async Task<HttpResponse> GetHttpResponseAsync(Uri uri, IProgress<double> progress = null)
{
HttpResponse response = null;
try try
{ {
@ -99,8 +88,6 @@ namespace MapControl
{ {
if (responseMessage.IsSuccessStatusCode) if (responseMessage.IsSuccessStatusCode)
{ {
byte[] buffer;
if (progress != null && responseMessage.Content.Headers.ContentLength.HasValue) if (progress != null && responseMessage.Content.Headers.ContentLength.HasValue)
{ {
buffer = await ReadAsByteArray(responseMessage.Content, progress).ConfigureAwait(false); buffer = await ReadAsByteArray(responseMessage.Content, progress).ConfigureAwait(false);
@ -110,7 +97,7 @@ namespace MapControl
buffer = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); buffer = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
} }
response = new HttpResponse(buffer, responseMessage.Headers.CacheControl?.MaxAge); maxAge = responseMessage.Headers.CacheControl?.MaxAge;
} }
else else
{ {
@ -127,7 +114,7 @@ namespace MapControl
Logger?.LogError(ex, "Failed loading {uri}", uri); Logger?.LogError(ex, "Failed loading {uri}", uri);
} }
return response; return (buffer, maxAge);
} }
private static async Task<byte[]> ReadAsByteArray(HttpContent content, IProgress<double> progress) private static async Task<byte[]> ReadAsByteArray(HttpContent content, IProgress<double> progress)

View file

@ -138,7 +138,27 @@ namespace MapControl
try try
{ {
await LoadTileImage(tile, tileSource, cacheName).ConfigureAwait(false); // Pass tileSource.LoadImageAsync calls to platform-specific method
// tile.LoadImageAsync(Func<Task<ImageSource>>) for completion in the UI thread.
if (string.IsNullOrEmpty(cacheName))
{
await tile.LoadImageAsync(() => tileSource.LoadImageAsync(tile.ZoomLevel, tile.Column, tile.Row)).ConfigureAwait(false);
}
else
{
var uri = tileSource.GetUri(tile.ZoomLevel, tile.Column, tile.Row);
if (uri != null)
{
var buffer = await LoadCachedBuffer(tile, uri, cacheName).ConfigureAwait(false);
if (buffer?.Length > 0)
{
await tile.LoadImageAsync(() => tileSource.LoadImageAsync(buffer)).ConfigureAwait(false);
}
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -147,31 +167,6 @@ namespace MapControl
} }
} }
private static async Task LoadTileImage(Tile tile, TileSource tileSource, string cacheName)
{
// Pass tileSource.LoadImageAsync calls to platform-specific method
// tile.LoadImageAsync(Func<Task<ImageSource>>) for execution on the UI thread in WinUI and UWP.
if (string.IsNullOrEmpty(cacheName))
{
await tile.LoadImageAsync(() => tileSource.LoadImageAsync(tile.ZoomLevel, tile.Column, tile.Row)).ConfigureAwait(false);
}
else
{
var uri = tileSource.GetUri(tile.ZoomLevel, tile.Column, tile.Row);
if (uri != null)
{
var buffer = await LoadCachedBuffer(tile, uri, cacheName).ConfigureAwait(false);
if (buffer?.Length > 0)
{
await tile.LoadImageAsync(() => tileSource.LoadImageAsync(buffer)).ConfigureAwait(false);
}
}
}
}
private static async Task<byte[]> LoadCachedBuffer(Tile tile, Uri uri, string cacheName) private static async Task<byte[]> LoadCachedBuffer(Tile tile, Uri uri, string cacheName)
{ {
var extension = Path.GetExtension(uri.LocalPath); var extension = Path.GetExtension(uri.LocalPath);
@ -182,42 +177,41 @@ namespace MapControl
} }
var cacheKey = $"{cacheName}/{tile.ZoomLevel}/{tile.Column}/{tile.Row}{extension}"; var cacheKey = $"{cacheName}/{tile.ZoomLevel}/{tile.Column}/{tile.Row}{extension}";
byte[] buffer = null;
try try
{ {
buffer = await Cache.GetAsync(cacheKey).ConfigureAwait(false); var cachedBuffer = await Cache.GetAsync(cacheKey).ConfigureAwait(false);
if (cachedBuffer != null)
{
return cachedBuffer;
}
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger?.LogError(ex, "Cache.GetAsync({cacheKey})", cacheKey); Logger?.LogError(ex, "Cache.GetAsync({cacheKey})", cacheKey);
} }
if (buffer == null) (var buffer, var maxAge) = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false);
if (buffer != null)
{ {
var response = await ImageLoader.GetHttpResponseAsync(uri).ConfigureAwait(false); try
if (response != null)
{ {
buffer = response.Buffer ?? Array.Empty<byte>(); // cache even if null, when no tile available var options = new DistributedCacheEntryOptions
try
{ {
var options = new DistributedCacheEntryOptions AbsoluteExpirationRelativeToNow =
{ !maxAge.HasValue ? DefaultCacheExpiration
AbsoluteExpirationRelativeToNow = : maxAge.Value < MinCacheExpiration ? MinCacheExpiration
!response.MaxAge.HasValue ? DefaultCacheExpiration : maxAge.Value > MaxCacheExpiration ? MaxCacheExpiration
: response.MaxAge.Value < MinCacheExpiration ? MinCacheExpiration : maxAge.Value
: response.MaxAge.Value > MaxCacheExpiration ? MaxCacheExpiration };
: response.MaxAge.Value
};
await Cache.SetAsync(cacheKey, buffer, options).ConfigureAwait(false); await Cache.SetAsync(cacheKey, buffer, options).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger?.LogError(ex, "Cache.SetAsync({cacheKey})", cacheKey); Logger?.LogError(ex, "Cache.SetAsync({cacheKey})", cacheKey);
}
} }
} }