using System.Threading.Tasks; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; using System; using System.Collections.Generic; using System.Linq; namespace MediaBrowser.Common.Implementations.ScheduledTasks { /// /// Class TaskManager /// public class TaskManager : ITaskManager { public event EventHandler TaskExecuting; public event EventHandler> TaskCompleted; /// /// Gets the list of Scheduled Tasks /// /// The scheduled tasks. public IScheduledTaskWorker[] ScheduledTasks { get; private set; } /// /// The _task queue /// private readonly List _taskQueue = new List(); /// /// Gets or sets the json serializer. /// /// The json serializer. private IJsonSerializer JsonSerializer { get; set; } /// /// Gets or sets the application paths. /// /// The application paths. private IApplicationPaths ApplicationPaths { get; set; } /// /// Gets the logger. /// /// The logger. private ILogger Logger { get; set; } /// /// Initializes a new instance of the class. /// /// The application paths. /// The json serializer. /// The logger. /// kernel public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger) { ApplicationPaths = applicationPaths; JsonSerializer = jsonSerializer; Logger = logger; ScheduledTasks = new IScheduledTaskWorker[] { }; } /// /// Cancels if running and queue. /// /// public void CancelIfRunningAndQueue() where T : IScheduledTask { var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); ((ScheduledTaskWorker)task).CancelIfRunning(); QueueScheduledTask(); } /// /// Queues the scheduled task. /// /// public void QueueScheduledTask() where T : IScheduledTask { var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); QueueScheduledTask(scheduledTask); } /// /// Queues the scheduled task. /// /// The task. public void QueueScheduledTask(IScheduledTask task) { var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == task.GetType()); QueueScheduledTask(scheduledTask); } /// /// Queues the scheduled task. /// /// The task. private void QueueScheduledTask(IScheduledTaskWorker task) { var type = task.ScheduledTask.GetType(); lock (_taskQueue) { // If it's idle just execute immediately if (task.State == TaskState.Idle) { ((ScheduledTaskWorker)task).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); } } } /// /// Adds the tasks. /// /// The tasks. public void AddTasks(IEnumerable tasks) { var myTasks = ScheduledTasks.ToList(); myTasks.AddRange(tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger))); ScheduledTasks = myTasks.ToArray(); } /// /// 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(); } } public void Cancel(IScheduledTaskWorker task) { ((ScheduledTaskWorker)task).Cancel(); } public Task Execute(IScheduledTaskWorker task) { return ((ScheduledTaskWorker)task).Execute(); } /// /// Called when [task executing]. /// /// The task. internal void OnTaskExecuting(IScheduledTask task) { EventHelper.QueueEventIfNotNull(TaskExecuting, task, EventArgs.Empty, Logger); } /// /// Called when [task completed]. /// /// The task. /// The result. internal void OnTaskCompleted(IScheduledTask task, TaskResult result) { EventHelper.QueueEventIfNotNull(TaskExecuting, task, new GenericEventArgs { Argument = result }, Logger); ExecuteQueuedTasks(); } /// /// Executes the queued tasks. /// private void ExecuteQueuedTasks() { // Execute queued tasks lock (_taskQueue) { foreach (var type in _taskQueue.ToList()) { var scheduledTask = ScheduledTasks.First(t => t.ScheduledTask.GetType() == type); if (scheduledTask.State == TaskState.Idle) { ((ScheduledTaskWorker)scheduledTask).Execute(); _taskQueue.Remove(type); } } } } } }