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);
            }
        }
Exemple #2
0
        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);
            }
        }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
        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);
            }
        }