diff --git a/MapControl/Shared/ImageLoader.cs b/MapControl/Shared/ImageLoader.cs
index 7aadf7bd..c2085cbb 100644
--- a/MapControl/Shared/ImageLoader.cs
+++ b/MapControl/Shared/ImageLoader.cs
@@ -8,7 +8,6 @@ using System.Diagnostics;
using System.Linq;
using System.IO;
using System.Net.Http;
-using System.Net.Http.Headers;
using System.Threading.Tasks;
#if WINDOWS_UWP
using Windows.UI.Xaml.Media;
@@ -23,10 +22,11 @@ namespace MapControl
public static partial class ImageLoader
{
///
- /// The HttpClient instance used when image data is downloaded from a web resource.
+ /// The System.Net.Http.HttpClient instance used when image data is downloaded via a http or https Uri.
///
public static HttpClient HttpClient { get; set; } = new HttpClient();
+
public static async Task LoadImageAsync(Uri uri)
{
ImageSource image = null;
@@ -39,24 +39,13 @@ namespace MapControl
}
else if (uri.Scheme == "http" || uri.Scheme == "https")
{
- using (var response = await HttpClient.GetAsync(uri))
- {
- if (response.IsSuccessStatusCode)
- {
- if (ImageAvailable(response.Headers))
- {
- using (var stream = new MemoryStream())
- {
- await response.Content.CopyToAsync(stream);
- stream.Seek(0, SeekOrigin.Begin);
+ var response = await GetHttpResponseAsync(uri);
- image = await LoadImageAsync(stream);
- }
- }
- }
- else
+ if (response?.Stream != null)
+ {
+ using (var stream = response.Stream)
{
- Debug.WriteLine("ImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
+ image = await LoadImageAsync(stream);
}
}
}
@@ -73,34 +62,21 @@ namespace MapControl
return image;
}
- internal class ImageStream : MemoryStream
+ internal static async Task GetHttpResponseAsync(Uri uri, bool continueOnCapturedContext = true)
{
- public TimeSpan? MaxAge { get; set; }
- }
-
- internal static async Task LoadImageStreamAsync(Uri uri)
- {
- ImageStream stream = null;
+ HttpResponse response = null;
try
{
- using (var response = await HttpClient.GetAsync(uri).ConfigureAwait(false))
+ using (var responseMessage = await HttpClient.GetAsync(uri).ConfigureAwait(continueOnCapturedContext))
{
- if (response.IsSuccessStatusCode)
+ if (responseMessage.IsSuccessStatusCode)
{
- stream = new ImageStream();
-
- if (ImageAvailable(response.Headers))
- {
- await response.Content.CopyToAsync(stream).ConfigureAwait(false);
- stream.Seek(0, SeekOrigin.Begin);
-
- stream.MaxAge = response.Headers.CacheControl?.MaxAge;
- }
+ response = await HttpResponse.Create(responseMessage, continueOnCapturedContext);
}
else
{
- Debug.WriteLine("ImageLoader: {0}: {1} {2}", uri, (int)response.StatusCode, response.ReasonPhrase);
+ Debug.WriteLine("ImageLoader: {0}: {1} {2}", uri, (int)responseMessage.StatusCode, responseMessage.ReasonPhrase);
}
}
}
@@ -109,14 +85,29 @@ namespace MapControl
Debug.WriteLine("ImageLoader: {0}: {1}", uri, ex.Message);
}
- return stream;
+ return response;
}
- private static bool ImageAvailable(HttpResponseHeaders responseHeaders)
+ internal class HttpResponse
{
- IEnumerable tileInfo;
+ public MemoryStream Stream { get; private set; }
+ public TimeSpan? MaxAge { get; private set; }
- return !responseHeaders.TryGetValues("X-VE-Tile-Info", out tileInfo) || !tileInfo.Contains("no-tile");
+ internal static async Task Create(HttpResponseMessage message, bool continueOnCapturedContext)
+ {
+ var response = new HttpResponse();
+ IEnumerable tileInfo;
+
+ if (!message.Headers.TryGetValues("X-VE-Tile-Info", out tileInfo) || !tileInfo.Contains("no-tile"))
+ {
+ response.Stream = new MemoryStream();
+ await message.Content.CopyToAsync(response.Stream).ConfigureAwait(continueOnCapturedContext);
+ response.Stream.Seek(0, SeekOrigin.Begin);
+ response.MaxAge = message.Headers.CacheControl?.MaxAge;
+ }
+
+ return response;
+ }
}
}
}
\ No newline at end of file
diff --git a/MapControl/Shared/TileImageLoader.cs b/MapControl/Shared/TileImageLoader.cs
index e3275c04..b9ca462c 100644
--- a/MapControl/Shared/TileImageLoader.cs
+++ b/MapControl/Shared/TileImageLoader.cs
@@ -107,6 +107,8 @@ namespace MapControl
try
{
+ Debug.WriteLine("TileImageLoader: loading {0}/{1}/{2} in thread {3}", tile.ZoomLevel, tile.XIndex, tile.Y, Environment.CurrentManagedThreadId);
+
await loadTileImage(tile).ConfigureAwait(false);
}
catch (Exception ex)
@@ -125,7 +127,7 @@ namespace MapControl
tileSource.UriFormat.StartsWith("http") &&
!string.IsNullOrEmpty(sourceName))
{
- loadTileImage = tile => LoadTileImageAsync(tile, tileSource, sourceName);
+ loadTileImage = tile => LoadCachedTileImageAsync(tile, tileSource, sourceName);
}
else
{
@@ -133,7 +135,7 @@ namespace MapControl
}
}
- private static async Task LoadTileImageAsync(Tile tile, TileSource tileSource, string sourceName)
+ private static async Task LoadCachedTileImageAsync(Tile tile, TileSource tileSource, string sourceName)
{
var uri = tileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
diff --git a/MapControl/UWP/TileImageLoader.UWP.cs b/MapControl/UWP/TileImageLoader.UWP.cs
index 12fb60d7..1c8c3cdf 100644
--- a/MapControl/UWP/TileImageLoader.UWP.cs
+++ b/MapControl/UWP/TileImageLoader.UWP.cs
@@ -36,17 +36,19 @@ namespace MapControl
if (cacheBuffer == null || cacheItem.Expiration < DateTime.UtcNow)
{
- using (var stream = await ImageLoader.LoadImageStreamAsync(uri).ConfigureAwait(false))
- {
- if (stream != null) // download succeeded
- {
- cacheBuffer = null; // discard cached image
+ var response = await ImageLoader.GetHttpResponseAsync(uri, false).ConfigureAwait(false);
- if (stream.Length > 0) // tile image available
+ if (response != null) // download succeeded
+ {
+ cacheBuffer = null; // discard cached image
+
+ if (response.Stream != null) // tile image available
+ {
+ using (var stream = response.Stream)
{
await SetTileImageAsync(tile, () => ImageLoader.LoadImageAsync(stream)).ConfigureAwait(false);
- await Cache.SetAsync(cacheKey, stream.ToArray().AsBuffer(), GetExpiration(stream.MaxAge)).ConfigureAwait(false);
+ await Cache.SetAsync(cacheKey, stream.ToArray().AsBuffer(), GetExpiration(response.MaxAge)).ConfigureAwait(false);
}
}
}
diff --git a/MapControl/WPF/TileImageLoader.WPF.cs b/MapControl/WPF/TileImageLoader.WPF.cs
index efb19097..9ff273d1 100644
--- a/MapControl/WPF/TileImageLoader.WPF.cs
+++ b/MapControl/WPF/TileImageLoader.WPF.cs
@@ -38,17 +38,19 @@ namespace MapControl
if (cacheBuffer == null || expiration < DateTime.UtcNow)
{
- using (var stream = await ImageLoader.LoadImageStreamAsync(uri).ConfigureAwait(false))
- {
- if (stream != null) // download succeeded
- {
- cacheBuffer = null; // discard cached image
+ var response = await ImageLoader.GetHttpResponseAsync(uri, false).ConfigureAwait(false);
- if (stream.Length > 0) // tile image available
+ if (response != null) // download succeeded
+ {
+ cacheBuffer = null; // discard cached image
+
+ if (response.Stream != null) // tile image available
+ {
+ using (var stream = response.Stream)
{
image = ImageLoader.LoadImage(stream);
- SetCachedImage(cacheKey, stream, GetExpiration(stream.MaxAge));
+ SetCachedImage(cacheKey, stream, GetExpiration(response.MaxAge));
}
}
}