protected void QueueImageLoadingTask(IImageLoaderTask task) { int position = Interlocked.Increment(ref _currentPosition); var currentPendingTask = new PendingTask() { Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task) }; PendingTask similarRunningTask = null; lock (_pendingTasksLock) { similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key); if (similarRunningTask == null) { Interlocked.Increment(ref _statsTotalPending); PendingTasks.Add(currentPendingTask); } else { similarRunningTask.Position = position; } } if (similarRunningTask == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache) { TakeFromPendingTasksAndRun(); } else { WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask); } }
protected void QueueImageLoadingTask(IImageLoaderTask task) { int position = Interlocked.Increment(ref _currentPosition); var currentPendingTask = new PendingTask() { Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task) }; if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { task?.Dispose(); return; } PendingTask similarRunningTask = null; lock (_pendingTasksLock) { if (!task.Parameters.Preload) { foreach (var pendingTask in PendingTasks.ToList()) // FMT: here we need a copy since cancelling will trigger them to be removed, hence collection is modified during enumeration { if (pendingTask.ImageLoadingTask != null && pendingTask.ImageLoadingTask.UsesSameNativeControl(task)) { pendingTask.ImageLoadingTask.CancelIfNeeded(); } } EvictStaleTasks(); } similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key); if (similarRunningTask == null) { Interlocked.Increment(ref _statsTotalPending); PendingTasks.Add(currentPendingTask); } else { similarRunningTask.Position = position; } } if (PauseWork) { return; } if (similarRunningTask == null || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache) { TakeFromPendingTasksAndRun(); } else { WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask); } }
public void AddTask(string taskName) { lock (Host) { PendingTasks.Add( new ExecutingTask() { Client = null, Complete = false, TaskName = taskName }); } UpdateTaskAssignments(); }
protected async void WaitForSimilarTaskFinished(PendingTask currentPendingTask, PendingTask taskForSimilarKey) { Interlocked.Increment(ref _statsTotalWaiting); if ((taskForSimilarKey?.FrameworkWrappingTask == null) || taskForSimilarKey.FrameworkWrappingTask.IsCanceled || taskForSimilarKey.FrameworkWrappingTask.IsFaulted) { lock (_pendingTasksLock) { Interlocked.Increment(ref _statsTotalPending); PendingTasks.Add(currentPendingTask); } TakeFromPendingTasksAndRun(); return; } Logger.Debug(string.Format("Wait for similar request for key: {0}", taskForSimilarKey.ImageLoadingTask.Key)); await taskForSimilarKey.FrameworkWrappingTask.ConfigureAwait(false); if ((currentPendingTask?.ImageLoadingTask == null) || currentPendingTask.ImageLoadingTask.IsCancelled) return; // Now our image should be in the cache var cacheFound = await currentPendingTask.ImageLoadingTask.TryLoadFromMemoryCacheAsync().ConfigureAwait(false); if (!cacheFound) { if ((currentPendingTask?.ImageLoadingTask == null) || currentPendingTask.ImageLoadingTask.IsCancelled) return; lock (_pendingTasksLock) { Interlocked.Increment(ref _statsTotalPending); PendingTasks.Add(currentPendingTask); } TakeFromPendingTasksAndRun(); } else { currentPendingTask?.ImageLoadingTask?.Dispose(); } }
/// <summary> /// Starts the <see cref="AbortableTask">Task</see> using <see cref="TaskManager.TaskFactory">TaskFactory</see> /// and adds it to the <see cref="TaskManager.Tasks">Tasks</see> collection or the /// <see cref="TaskManager.PendingTasks">PendingTasks</see> collection if no threads are available. /// </summary> /// <param name="task"></param> public void StartTask(AbortableTask task) { if (MaximumConcurrency <= RunningTasks.Count()) { PendingTasks.Add(task); } else { Tasks.Add(task); if (TaskFactory.Scheduler == null) { task.Task.Start(); } else { task.Task.Start(TaskFactory.Scheduler); } } }
protected void QueueImageLoadingTask(IImageLoaderTask task) { var position = Interlocked.Increment(ref _currentPosition); var currentPendingTask = new PendingTask { Position = position, ImageLoadingTask = task, FrameworkWrappingTask = CreateFrameworkTask(task) }; if (task.IsCancelled || task.IsCompleted || ExitTasksEarly) { task?.Dispose(); return; } PendingTask similarRunningTask = null; lock (_pendingTasksLock) { if (!task.Parameters.Preload) { foreach (var pendingTask in PendingTasks.ToList()) // FMT: here we need a copy since cancelling will trigger them to be removed, hence collection is modified during enumeration if ((pendingTask.ImageLoadingTask != null) && pendingTask.ImageLoadingTask.UsesSameNativeControl(task)) pendingTask.ImageLoadingTask.CancelIfNeeded(); EvictStaleTasks(); } similarRunningTask = PendingTasks.FirstOrDefault(t => t.ImageLoadingTask.Key == task.Key); if (similarRunningTask == null) { Interlocked.Increment(ref _statsTotalPending); PendingTasks.Add(currentPendingTask); } else if (similarRunningTask.ImageLoadingTask != null) { if (task.Parameters.Priority.HasValue && (!similarRunningTask.ImageLoadingTask.Parameters.Priority.HasValue || (task.Parameters.Priority.Value > similarRunningTask.ImageLoadingTask.Parameters.Priority.Value))) similarRunningTask.ImageLoadingTask.Parameters.WithPriority(task.Parameters.Priority.Value); if (task.Parameters.OnDownloadProgress != null) { var similarTaskOnDownloadProgress = similarRunningTask.ImageLoadingTask.Parameters.OnDownloadProgress; similarRunningTask.ImageLoadingTask.Parameters.DownloadProgress(obj => { similarTaskOnDownloadProgress?.Invoke(obj); task.Parameters.OnDownloadProgress(obj); }); } } } if (PauseWork) return; if ((similarRunningTask == null) || !currentPendingTask.ImageLoadingTask.CanUseMemoryCache) TakeFromPendingTasksAndRun(); else WaitForSimilarTaskFinished(currentPendingTask, similarRunningTask); }