using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Linq; namespace MediaBrowser.Common.ScheduledTasks { /// /// Class TaskManager /// internal class TaskManager : ITaskManager { /// /// Gets the list of Scheduled Tasks /// /// The scheduled tasks. public IScheduledTask[] ScheduledTasks { get; private set; } /// /// The _task queue /// private readonly List _taskQueue = new List(); /// /// The _logger /// private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The logger. public TaskManager(ILogger logger) { if (logger == null) { throw new ArgumentException("logger"); } _logger = logger; ScheduledTasks = new IScheduledTask[] {}; } /// /// Cancels if running and queue. /// /// public void CancelIfRunningAndQueue() where T : IScheduledTask { ScheduledTasks.OfType().First().CancelIfRunning(); QueueScheduledTask(); } /// /// Queues the scheduled task. /// /// public void QueueScheduledTask() where T : IScheduledTask { var scheduledTask = ScheduledTasks.OfType().First(); QueueScheduledTask(scheduledTask); } /// /// Queues the scheduled task. /// /// The task. public void QueueScheduledTask(IScheduledTask task) { var type = task.GetType(); var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); lock (_taskQueue) { // If it's idle just execute immediately if (scheduledTask.State == TaskState.Idle) { scheduledTask.Execute(); return; } if (!_taskQueue.Contains(type)) { _logger.Info("Queueing task {0}", type.Name); _taskQueue.Add(type); } else { _logger.Info("Task already queued: {0}", type.Name); } } } /// /// Called when [task completed]. /// /// The task. public void OnTaskCompleted(IScheduledTask task) { // Execute queued tasks lock (_taskQueue) { var copy = _taskQueue.ToList(); foreach (var type in copy) { var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); if (scheduledTask.State == TaskState.Idle) { scheduledTask.Execute(); _taskQueue.Remove(type); } } } } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool dispose) { foreach (var task in ScheduledTasks) { task.Dispose(); } } /// /// Adds the tasks. /// /// The tasks. public void AddTasks(IEnumerable tasks) { var myTasks = ScheduledTasks.ToList(); myTasks.AddRange(tasks); ScheduledTasks = myTasks.ToArray(); } } }