public virtual async void LoadImage(IImageLoaderTask task) { try { Interlocked.Increment(ref _loadCount); if (task == null) { return; } if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { if (!task.IsCompleted) { task.TryDispose(); } return; } if (Configuration.VerbosePerformanceLogging && (_loadCount % 10) == 0) { LogSchedulerStats(); } if (task?.Parameters?.Source != ImageSource.Stream && string.IsNullOrWhiteSpace(task?.Parameters?.Path)) { Logger.Error("ImageService: null path ignored"); task.TryDispose(); return; } await task.Init(); // If we have the image in memory then it's pointless to schedule the job: just display it straight away if (task.CanUseMemoryCache && await task.TryLoadFromMemoryCacheAsync().ConfigureAwait(false)) { Interlocked.Increment(ref _statsTotalMemoryCacheHits); task.TryDispose(); return; } QueueImageLoadingTask(task); } catch (Exception ex) { Logger.Error(string.Format("Image loaded failed: {0}", task?.Key), ex); } }
public virtual void LoadImage(IImageLoaderTask task) { try { Interlocked.Increment(ref _loadCount); if (task == null) { return; } if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { if (!task.IsCompleted) { task.TryDispose(); } return; } if (_imageLoader.VerbosePerformanceLogging && (_loadCount % 10) == 0) { LogSchedulerStats(_imageLoader.Performance); } if (string.IsNullOrWhiteSpace(task.KeyRaw)) { _imageLoader.Logger?.Error("ImageService: Key cannot be null"); task.TryDispose(); return; } // If we have the image in memory then it's pointless to schedule the job: just display it straight away if (task.CanUseMemoryCache && task.TryLoadFromMemoryCache()) { Interlocked.Increment(ref _statsTotalMemoryCacheHits); task.TryDispose(); return; } QueueImageLoadingTask(task); } catch (Exception ex) { _imageLoader.Logger?.Error($"Image loaded failed: {task?.Key}", ex); } }
protected void QueueImageLoadingTask(IImageLoaderTask task) { if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { if (!task.IsCompleted) { task.TryDispose(); } return; } IImageLoaderTask similarRunningTask = null; similarRunningTask = PendingTasks.FirstOrDefaultByRawKey(task.KeyRaw); if (similarRunningTask == null) { Interlocked.Increment(ref _statsTotalPending); Enqueue(task); } else { if (task.Parameters.Priority.HasValue && (!similarRunningTask.Parameters.Priority.HasValue || task.Parameters.Priority.Value > similarRunningTask.Parameters.Priority.Value)) { similarRunningTask.Parameters.WithPriority(task.Parameters.Priority.Value); PendingTasks.TryUpdatePriority(similarRunningTask, task.Parameters.Priority.Value); } if (task.Parameters.OnDownloadProgress != null) { var similarTaskOnDownloadProgress = similarRunningTask.Parameters.OnDownloadProgress; similarRunningTask.Parameters.DownloadProgress((DownloadProgress obj) => { similarTaskOnDownloadProgress?.Invoke(obj); task.Parameters.OnDownloadProgress(obj); }); } } if (PauseWork) { return; } if (similarRunningTask == null || !task.CanUseMemoryCache) { TakeFromPendingTasksAndRun(); } else { Interlocked.Increment(ref _statsTotalWaiting); Logger.Debug(string.Format("Wait for similar request for key: {0}", task.Key)); SimilarTasks.Add(task); } }
protected async Task RunImageLoadingTaskAsync(IImageLoaderTask pendingTask) { string keyRaw = pendingTask.KeyRaw; try { if (_imageLoader.VerbosePerformanceLogging) { IPlatformPerformance performance = _imageLoader.Performance; LogSchedulerStats(performance); var stopwatch = Stopwatch.StartNew(); await pendingTask.RunAsync().ConfigureAwait(false); stopwatch.Stop(); _imageLoader.Logger?.Debug(string.Format("[PERFORMANCE] RunAsync - NetManagedThreadId: {0}, NativeThreadId: {1}, Execution: {2} ms, Key: {3}", performance.GetCurrentManagedThreadId(), performance.GetCurrentSystemThreadId(), stopwatch.Elapsed.Milliseconds, pendingTask.Key)); } else { await pendingTask.RunAsync().ConfigureAwait(false); } } finally { lock (_lock) { RunningTasks.Remove(keyRaw); if (SimilarTasks.Count > 0) { SimilarTasks.RemoveAll(v => v == null || v.IsCompleted || v.IsCancelled); var similarItems = SimilarTasks.Where(v => v.KeyRaw == keyRaw); foreach (var similar in similarItems) { SimilarTasks.Remove(similar); LoadImage(similar); } } } pendingTask.TryDispose(); await TakeFromPendingTasksAndRunAsync().ConfigureAwait(false); } }
protected void QueueImageLoadingTask(IImageLoaderTask task) { if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { if (!task.IsCompleted) { task.TryDispose(); } return; } IImageLoaderTask?similarRunningTask = null; similarRunningTask = PendingTasks.FirstOrDefaultByRawKey(task.KeyRaw); if (similarRunningTask == null) { Interlocked.Increment(ref _statsTotalPending); Enqueue(task); } else { if (task.Priority.HasValue && (!similarRunningTask.Priority.HasValue || task.Priority.Value > similarRunningTask.Priority.Value)) { similarRunningTask.Priority = task.Priority.Value; PendingTasks.TryUpdatePriority(similarRunningTask, task.Priority.Value); } #if LATER similarRunningTask.ImageSource.DownloadProgress += (sender, args) => task.ImageSource.RaiseDownloadProgress(args); #endif } if (PauseWork) { return; } if (similarRunningTask == null || !task.CanUseMemoryCache) { TakeFromPendingTasksAndRun(); } else { Interlocked.Increment(ref _statsTotalWaiting); _imageLoader.Logger?.Debug($"Wait for similar request for key: {task.Key}"); SimilarTasks.Add(task); } }