Created
June 22, 2015 00:33
-
-
Save programmation/17ca82eefb5d3d87012e to your computer and use it in GitHub Desktop.
How to make sure only one ImageSource load is in flight at a time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://bugzilla.xamarin.com/show_bug.cgi?id=21981#c5 | |
using Xamarin.Forms; | |
[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(iOS.Renderers.ImageLoaderSourceHandler))] | |
namespace iOS.Renderers | |
{ | |
using System.Collections.Generic; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using MonoTouch.UIKit; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.iOS; | |
public sealed class ImageLoaderSourceHandler : IImageSourceHandler | |
{ | |
private static readonly Dictionary<string, | |
TaskCompletionSource<object>> CurrentCalls = new Dictionary<string, | |
TaskCompletionSource<object>>(); | |
private static readonly object LockObj = new object(); | |
public async Task<UIImage> LoadImageAsync(ImageSource imagesource, | |
CancellationToken cancelationToken = new CancellationToken(), float scale = 1) | |
{ | |
var uriImageSource = imagesource as UriImageSource; | |
if (uriImageSource != null && uriImageSource.Uri != null) | |
{ | |
var key = uriImageSource.Uri.ToString(); | |
TaskCompletionSource<object> existingTask = null; | |
lock (LockObj) | |
{ | |
if (CurrentCalls.ContainsKey(key)) | |
existingTask = CurrentCalls[key]; | |
} | |
if (existingTask != null) | |
await existingTask.Task; | |
var task = new TaskCompletionSource<object>(); | |
lock (LockObj) | |
CurrentCalls.Add(key, task); | |
var originalImageLoaderSourceHandler = new | |
Xamarin.Forms.Platform.iOS.ImageLoaderSourceHandler(); | |
var uiImage = await originalImageLoaderSourceHandler | |
.LoadImageAsync(imagesource, cancelationToken, scale); | |
lock (LockObj) | |
CurrentCalls.Remove(key); | |
task.SetResult(null); | |
return uiImage; | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment