Skip to content

Instantly share code, notes, and snippets.

@programmation
Created June 22, 2015 00:33
Show Gist options
  • Save programmation/17ca82eefb5d3d87012e to your computer and use it in GitHub Desktop.
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
// 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