protected virtual async Task ShowPlaceholder(string path, string key, ImageSource source, bool isLoadingPlaceholder) { if (Parameters.Preload) { return; } if (!await TryLoadFromMemoryCacheAsync(key, false, false, isLoadingPlaceholder).ConfigureAwait(false)) { try { var customResolver = isLoadingPlaceholder ? Parameters.CustomLoadingPlaceholderDataResolver : Parameters.CustomErrorPlaceholderDataResolver; var loadResolver = customResolver ?? DataResolverFactory.GetResolver(path, source, Parameters, Configuration); loadResolver = new WrappedDataResolver(loadResolver); Tuple <Stream, LoadingResult, ImageInformation> loadImageData; bool hasMutex = false; TImageContainer loadImage; try { hasMutex = await _placeholdersResolveLock.WaitAsync(TimeSpan.FromSeconds(3), CancellationTokenSource.Token).ConfigureAwait(false); ThrowIfCancellationRequested(); if (await TryLoadFromMemoryCacheAsync(key, false, false, isLoadingPlaceholder).ConfigureAwait(false)) { if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; } return; } ThrowIfCancellationRequested(); loadImageData = await loadResolver.Resolve(path, Parameters, CancellationTokenSource.Token).ConfigureAwait(false); ThrowIfCancellationRequested(); using (loadImageData.Item1) { loadImage = await GenerateImageAsync(path, source, loadImageData.Item1, loadImageData.Item3, TransformPlaceholders, true).ConfigureAwait(false); if (loadImage != default(TImageContainer)) { MemoryCache.Add(key, loadImageData.Item3, loadImage); } } } finally { if (hasMutex) { _placeholdersResolveLock.Release(); } } ThrowIfCancellationRequested(); if (isLoadingPlaceholder) { PlaceholderWeakReference = new WeakReference <TImageContainer>(loadImage); } await SetTargetAsync(loadImage, false).ConfigureAwait(false); if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; } } catch (Exception ex) { Logger.Error("Setting placeholder failed", ex); } } else if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; } }
public async Task RunAsync() { LoadingResult loadingResult = LoadingResult.Failed; bool success = false; try { if (IsCompleted || IsCancelled || ImageService.ExitTasksEarly) { throw new OperationCanceledException(); } ThrowIfCancellationRequested(); // LOAD IMAGE if (!(await TryLoadFromMemoryCacheAsync().ConfigureAwait(false))) { Logger.Debug(string.Format("Generating/retrieving image: {0}", Key)); var resolver = Parameters.CustomDataResolver ?? DataResolverFactory.GetResolver(Parameters.Path, Parameters.Source, Parameters, Configuration); resolver = new WrappedDataResolver(resolver); var imageData = await resolver.Resolve(Parameters.Path, Parameters, CancellationTokenSource.Token).ConfigureAwait(false); loadingResult = imageData.Item2; using (imageData.Item1) { ImageInformation = imageData.Item3; ImageInformation.SetKey(Key, Parameters.CustomCacheKey); ImageInformation.SetPath(Parameters.Path); ThrowIfCancellationRequested(); // Preload if (Parameters.Preload && Parameters.CacheType.HasValue && Parameters.CacheType.Value == CacheType.Disk) { if (loadingResult == LoadingResult.Internet) { Logger?.Debug(string.Format("DownloadOnly success: {0}", Key)); } success = true; return; } ThrowIfCancellationRequested(); var image = await GenerateImageAsync(Parameters.Path, Parameters.Source, imageData.Item1, imageData.Item3, true, false).ConfigureAwait(false); ThrowIfCancellationRequested(); try { BeforeLoading(image, false); if (image != default(TImageContainer) && CanUseMemoryCache) { MemoryCache.Add(Key, imageData.Item3, image); } ThrowIfCancellationRequested(); bool isFadeAnimationEnabled = Parameters.FadeAnimationEnabled ?? Configuration.FadeAnimationEnabled; await SetTargetAsync(image, isFadeAnimationEnabled).ConfigureAwait(false); } finally { AfterLoading(image, false); } } } success = true; } catch (Exception ex) { if (ex is OperationCanceledException || ex is ObjectDisposedException) { if (Configuration.VerboseLoadingCancelledLogging) { Logger.Debug(string.Format("Image loading cancelled: {0}", Key)); } } else { if (_clearCacheOnOutOfMemory && ex is OutOfMemoryException) { MemoryCache.Clear(); } Logger.Error(string.Format("Image loading failed: {0}", Key), ex); if (Configuration.ExecuteCallbacksOnUIThread && Parameters?.OnError != null) { await MainThreadDispatcher.PostAsync(() => { Parameters?.OnError?.Invoke(ex); }).ConfigureAwait(false); } else { Parameters?.OnError?.Invoke(ex); } try { // Error placeholder if enabled if (!Parameters.Preload && !string.IsNullOrWhiteSpace(Parameters.ErrorPlaceholderPath)) { await ShowPlaceholder(Parameters.ErrorPlaceholderPath, KeyForErrorPlaceholder, Parameters.ErrorPlaceholderSource, false).ConfigureAwait(false); } } catch (Exception ex2) { if (!(ex2 is OperationCanceledException)) { Logger.Error(string.Format("Image loading failed: {0}", Key), ex); } } } } finally { try { if (CancellationTokenSource?.IsCancellationRequested == false) { CancellationTokenSource.Cancel(); } } catch (Exception) { } IsCompleted = true; using (Parameters) { if (Configuration.ExecuteCallbacksOnUIThread && Parameters?.OnFinish != null) { await MainThreadDispatcher.PostAsync(() => { if (success) { Parameters?.OnSuccess?.Invoke(ImageInformation, loadingResult); } Parameters?.OnFinish?.Invoke(this); }).ConfigureAwait(false); } else { if (success) { Parameters?.OnSuccess?.Invoke(ImageInformation, loadingResult); } Parameters?.OnFinish?.Invoke(this); } ImageService.RemovePendingTask(this); } } }
protected virtual async Task ShowPlaceholder(string path, string key, ImageSource source, bool isLoadingPlaceholder) { if (Parameters.Preload) { return; } if (!await TryLoadFromMemoryCacheAsync(key, false, false, isLoadingPlaceholder).ConfigureAwait(false)) { try { var customResolver = isLoadingPlaceholder ? Parameters.CustomLoadingPlaceholderDataResolver : Parameters.CustomErrorPlaceholderDataResolver; var loadResolver = customResolver ?? DataResolverFactory.GetResolver(path, source, Parameters, Configuration); loadResolver = new WrappedDataResolver(loadResolver); DataResolverResult loadImageData; TImageContainer loadImage; if (!await _placeholdersResolveLock.WaitAsync(TimeSpan.FromSeconds(10), CancellationTokenSource.Token).ConfigureAwait(false)) { return; } try { ThrowIfCancellationRequested(); if (await TryLoadFromMemoryCacheAsync(key, false, false, isLoadingPlaceholder).ConfigureAwait(false)) { if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; Parameters.OnLoadingPlaceholderSet?.Invoke(); } return; } ThrowIfCancellationRequested(); loadImageData = await loadResolver.Resolve(path, Parameters, CancellationTokenSource.Token).ConfigureAwait(false); ThrowIfCancellationRequested(); if (loadImageData.Stream != null) { using (loadImageData.Stream) { loadImage = await GenerateImageAsync(path, source, loadImageData.Stream, loadImageData.ImageInformation, TransformPlaceholders, true).ConfigureAwait(false); } } else { loadImage = loadImageData.ImageContainer as TImageContainer; } if (loadImage != default(TImageContainer)) { MemoryCache.Add(key, loadImageData.ImageInformation, loadImage); } } finally { _placeholdersResolveLock.Release(); } ThrowIfCancellationRequested(); if (isLoadingPlaceholder) { PlaceholderWeakReference = new WeakReference <TImageContainer>(loadImage); } if (Target != null) { await SetTargetAsync(loadImage, false).ConfigureAwait(false); } if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; Parameters.OnLoadingPlaceholderSet?.Invoke(); } } catch (Exception ex) { if (ex is OperationCanceledException) { throw; } Logger.Error("Setting placeholder failed", ex); } } else if (isLoadingPlaceholder) { _isLoadingPlaceholderLoaded = true; Parameters.OnLoadingPlaceholderSet?.Invoke(); } }