Example #1
0
 private void WaitForAvailableThread()
 {
     System.DateTime dtStart = System.DateTime.Now;
     while (!disposing && MaximumConcurrency <= RunningTasks.Count())
     {
         System.Threading.Thread.Sleep(10);
         if (System.DateTime.Now - dtStart >= TimeOut)
         {
             throw new System.TimeoutException(
                       string.Format(IO.FileParser.Properties.Resources.ResourceManager.GetString("ThreadNotAvailable"),
                                     TimeOut.ToString("HH:mm:ss.fff")));
         }
     }
 }
Example #2
0
 /// <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);
         }
     }
 }
Example #3
0
        protected async Task TakeFromPendingTasksAndRunAsync()
        {
            if (PendingTasks.Count == 0)
            {
                return;
            }

            Dictionary <string, IImageLoaderTask> tasksToRun = null;

            int preloadOrUrlTasksCount = 0;
            int urlTasksCount          = 0;
            int preloadTasksCount      = 0;

            lock (_lock)
            {
                if (RunningTasks.Count >= MaxParallelTasks)
                {
                    urlTasksCount          = RunningTasks.Count(v => v.Value != null && (!v.Value.Parameters.Preload && v.Value.Parameters.Source == ImageSource.Url));
                    preloadTasksCount      = RunningTasks.Count(v => v.Value != null && v.Value.Parameters.Preload);
                    preloadOrUrlTasksCount = preloadTasksCount + urlTasksCount;

                    if (preloadOrUrlTasksCount == 0 || preloadOrUrlTasksCount != MaxParallelTasks)
                    {
                        return;
                    }

                    // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation
                    if (RunningTasks.Count - Math.Max(1, Math.Min(preloadOrUrlTasksCount, MaxParallelTasks / 2)) >= MaxParallelTasks)
                    {
                        return;
                    }
                }

                int numberOfTasks = MaxParallelTasks - RunningTasks.Count + Math.Min(preloadOrUrlTasksCount, MaxParallelTasks / 2);
                tasksToRun = new Dictionary <string, IImageLoaderTask>();
                IImageLoaderTask task = null;

                while (tasksToRun.Count < numberOfTasks && PendingTasks.TryDequeue(out task))
                {
                    if (task == null || task.IsCancelled || task.IsCompleted)
                    {
                        continue;
                    }

                    // We don't want to load, at the same time, images that have same key or same raw key at the same time
                    // This way we prevent concurrent downloads and benefit from caches
                    string rawKey = task.KeyRaw;
                    if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey))
                    {
                        SimilarTasks.Add(task);
                        continue;
                    }

                    if (preloadOrUrlTasksCount != 0)
                    {
                        if (!task.Parameters.Preload && (urlTasksCount == 0 || task.Parameters.Source != ImageSource.Url))
                        {
                            tasksToRun.Add(rawKey, task);
                        }
                        else
                        {
                            Enqueue(task);
                            break;
                        }
                    }
                    else
                    {
                        tasksToRun.Add(rawKey, task);
                    }
                }

                foreach (var item in tasksToRun)
                {
                    RunningTasks.Add(item.Key, item.Value);
                    Interlocked.Increment(ref _statsTotalRunning);
                }
            }

            if (tasksToRun != null && tasksToRun.Count > 0)
            {
                var tasks = tasksToRun.Select(p => RunImageLoadingTaskAsync(p.Value));
                await Task.WhenAll(tasks).ConfigureAwait(false);
            }
        }
Example #4
0
        protected async Task TakeFromPendingTasksAndRunAsync()
        {
            Dictionary<string, PendingTask> tasksToRun = null;

            lock (_pendingTasksLock)
            {
                var preloadOrUrlTasksCount = 0;
                var urlTasksCount = 0;
                var preloadTasksCount = 0;

                if (RunningTasks.Count >= MaxParallelTasks)
                {
                    urlTasksCount =
                        RunningTasks.Count(
                            v =>
                                (v.Value?.ImageLoadingTask != null) && !v.Value.ImageLoadingTask.Parameters.Preload &&
                                (v.Value.ImageLoadingTask.Parameters.Source == ImageSource.Url));

                    preloadTasksCount = RunningTasks.Count(v => (v.Value?.ImageLoadingTask != null)
                                                                && v.Value.ImageLoadingTask.Parameters.Preload);
                    preloadOrUrlTasksCount = preloadTasksCount + urlTasksCount;

                    if ((preloadOrUrlTasksCount == 0) || (preloadOrUrlTasksCount != MaxParallelTasks))
                        return;

                    // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation
                    if (RunningTasks.Count - Math.Max(1, Math.Min(preloadOrUrlTasksCount, MaxParallelTasks/2)) >=
                        MaxParallelTasks)
                        return;
                }

                var numberOfTasks = MaxParallelTasks - RunningTasks.Count +
                                    Math.Min(preloadOrUrlTasksCount, MaxParallelTasks/2);
                tasksToRun = new Dictionary<string, PendingTask>();

                foreach (
                    var task in
                    PendingTasks.Where(t => !t.ImageLoadingTask.IsCancelled && !t.ImageLoadingTask.IsCompleted)
                        .OrderByDescending(
                            t =>
                                t.ImageLoadingTask.Parameters.Priority ??
                                GetDefaultPriority(t.ImageLoadingTask.Parameters.Source))
                        .ThenBy(t => t.Position))
                {
                    // We don't want to load, at the same time, images that have same key or same raw key at the same time
                    // This way we prevent concurrent downloads and benefit from caches

                    var rawKey = task.ImageLoadingTask.KeyRaw;
                    if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey))
                        continue;

                    if (preloadOrUrlTasksCount != 0)
                    {
                        if (!task.ImageLoadingTask.Parameters.Preload &&
                            ((urlTasksCount == 0) || (task.ImageLoadingTask.Parameters.Source != ImageSource.Url)))
                            tasksToRun.Add(rawKey, task);
                    }
                    else
                    {
                        tasksToRun.Add(rawKey, task);
                    }

                    if (tasksToRun.Count == numberOfTasks)
                        break;
                }
            }

            if ((tasksToRun != null) && (tasksToRun.Count > 0))
                if (tasksToRun.Count == 1)
                {
                    await RunImageLoadingTaskAsync(tasksToRun.Values.First()).ConfigureAwait(false);
                }
                else
                {
                    var tasks = tasksToRun.Select(p => RunImageLoadingTaskAsync(p.Value));
                    await Task.WhenAll(tasks).ConfigureAwait(false);
                }
        }
Example #5
0
        public override async Task ExecuteAsync(object parameter)
        {
            _shell.StatusText = $"Open Async task {Thread.CurrentThread.ManagedThreadId } of {RunningTasks.Count()} ";

            await Task.Delay(2000);

            _shell.StatusText = $"Completed Open Async task {Thread.CurrentThread.ManagedThreadId } of {RunningTasks.Count()} ";
        }
Example #6
0
        protected async Task TakeFromPendingTasksAndRunAsync()
        {
            if (PendingTasks.Count == 0)
            {
                return;
            }

            Dictionary <string, IImageLoaderTask>?tasksToRun = null;

            int urlTasksCount = 0;

            lock (_lock)
            {
                if (RunningTasks.Count >= MaxParallelTasks)
                {
                    urlTasksCount = RunningTasks.Count(v => v.Value != null && v.Value.ImageSource.Source is UriSource);

                    if (urlTasksCount == 0 || urlTasksCount != MaxParallelTasks)
                    {
                        return;
                    }

                    // Allow only half of MaxParallelTasks as additional allowed tasks when preloading occurs to prevent starvation
                    if (RunningTasks.Count - Math.Max(1, Math.Min(urlTasksCount, MaxParallelTasks / 2)) >= MaxParallelTasks)
                    {
                        return;
                    }
                }

                int numberOfTasks = MaxParallelTasks - RunningTasks.Count + Math.Min(urlTasksCount, MaxParallelTasks / 2);
                tasksToRun = new Dictionary <string, IImageLoaderTask>();

                while (tasksToRun.Count < numberOfTasks && PendingTasks.TryDequeue(out IImageLoaderTask? task))
                {
                    if (task == null || task.IsCancelled || task.IsCompleted)
                    {
                        continue;
                    }

                    // We don't want to load, at the same time, images that have same key or same raw key at the same time
                    // This way we prevent concurrent downloads and benefit from caches
                    string rawKey = task.KeyRaw;
                    if (RunningTasks.ContainsKey(rawKey) || tasksToRun.ContainsKey(rawKey))
                    {
                        SimilarTasks.Add(task);
                        continue;
                    }

                    if (urlTasksCount != 0)
                    {
                        if (!(task.ImageSource.Source is UriSource))
                        {
                            tasksToRun.Add(rawKey, task);
                        }
                        else
                        {
                            Enqueue(task);
                            break;
                        }
                    }
                    else
                    {
                        tasksToRun.Add(rawKey, task);
                    }
                }

                foreach (var item in tasksToRun)
                {
                    RunningTasks.Add(item.Key, item.Value);
                    Interlocked.Increment(ref _statsTotalRunning);
                }
            }

            if (tasksToRun != null && tasksToRun.Count > 0)
            {
                var tasks = tasksToRun.Select(async p =>
                {
                    await Task.Factory.StartNew(async() =>
                    {
                        try
                        {
                            await RunImageLoadingTaskAsync(p.Value).ConfigureAwait(false);
                        }
                        catch (Exception ex)
                        {
                            _imageLoader.Logger?.Error("TakeFromPendingTasksAndRun exception", ex);
                        }
                    }, CancellationToken.None, TaskCreationOptions.PreferFairness | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler, TaskScheduler.Default).ConfigureAwait(false);
                });
                await Task.WhenAll(tasks).ConfigureAwait(false);
            }
        }