using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace PalGain.Core.Tasks
{
///
/// Represents task manager
///
public partial class TaskManager
{
private static readonly TaskManager _taskManager = new TaskManager();
private readonly List _taskThreads = new List();
private int _notRunTasksInterval = 60 * 30; //30 minutes
private TaskManager()
{
}
///
/// Initializes the task manager with the property values specified in the configuration file.
///
public void Initialize()
{
this._taskThreads.Clear();
var taskService = PalGainEngine.Instance.Resolve();
var scheduleTasks = taskService
.GetAllTasks()
.Where(p => p.Enabled == true)
.OrderBy(x => x.Seconds)
.ToList();
//group by threads with the same seconds
foreach (var scheduleTaskGrouped in scheduleTasks.GroupBy(x => x.Seconds))
{
//create a thread
var taskThread = new TaskThread
{
Seconds = scheduleTaskGrouped.Key
};
foreach (var scheduleTask in scheduleTaskGrouped)
{
var task = new Task(scheduleTask);
taskThread.AddTask(task);
}
this._taskThreads.Add(taskThread);
}
//sometimes a task period could be set to several hours (or even days).
//in this case a probability that it'll be run is quite small (an application could be restarted)
//we should manually run the tasks which weren't run for a long time
var notRunTasks = scheduleTasks
//find tasks with "run period" more than 30 minutes
.Where(x => x.Seconds >= _notRunTasksInterval)
.Where(x => !x.LastStartUtc.HasValue || x.LastStartUtc.Value.AddSeconds(x.Seconds) < DateTime.UtcNow)
.ToList();
//create a thread for the tasks which weren't run for a long time
if (notRunTasks.Count > 0)
{
var taskThread = new TaskThread
{
RunOnlyOnce = true,
Seconds = 60 * 5 //let's run such tasks in 5 minutes after application start
};
foreach (var scheduleTask in notRunTasks)
{
var task = new Task(scheduleTask);
taskThread.AddTask(task);
}
this._taskThreads.Add(taskThread);
}
}
///
/// Starts the task manager
///
public void Start()
{
foreach (var taskThread in this._taskThreads)
{
taskThread.InitTimer();
}
}
///
/// Stops the task manager
///
public void Stop()
{
foreach (var taskThread in this._taskThreads)
{
taskThread.Dispose();
}
}
///
/// Gets the task mamanger instance
///
public static TaskManager Instance
{
get
{
return _taskManager;
}
}
///
/// Gets a list of task threads of this task manager
///
public IList TaskThreads
{
get
{
return new ReadOnlyCollection(this._taskThreads);
}
}
}
}