Cómo persistir un objeto que tiene métodos y delegados
Normalmente usamos el XmlSerializer para persistir objetos en disco, para clases simples nos sirve, pero el problema es cuando intentamos persistir clases más complejas con delegados y métodos no nos sirve. Un escenario de uso puede ser planificador de tareas. Para empezamos a crear la clase que vamos a persistir.
[Serializable]
public class Tarea
{
[Serializable]
public delegate void TareaDelegate();
private readonly TareaDelegate tarea;
public Tarea(TareaDelegate Task, DateTime FechaEjecucion)
{
ejecutada = false;
tarea = Task;
fechaEjecucion = FechaEjecucion;
}
private bool ejecutada;
public bool Ejecutada
{
get { return ejecutada; }
}
private readonly DateTime fechaEjecucion;
public DateTime FechaEjecucion
{
get { return fechaEjecucion; }
}
public void Ejecutar()
{
if ((FechaEjecucion < DateTime.Now & Ejecutada == false))
{
tarea();
ejecutada = true;
}
}
}
Son muy importantes las etiquetas Serializable tanto de la clase como del delegado ya que sino no funcionará la persistencia. Como véis la clase es bastante sencilla: un delegado, una variable del delegado, una serie de propiedades y el método ejecutar que si se ha cumplido unas condiciones se ejecuta.
En nuestro caso estamos haciendo el ejemplo en una aplicación de consola, en la clase de ésta vamos a incluír los dos siguientes métodos:
public static void Tarea1()
{
Console.WriteLine("Hola");
}
public static void Tarea2()
{
Console.WriteLine("Adios ;)");
}
Y en el método Main escribimos lo siguiente:
//Creamos una lista de tareas
var ListaDeTareas = new List<Tarea>();
//Declaramos un par de tareas, les ponemos como fecha de ejecución
//ahora para que se ejecuten en el mismo momento
var Tarea1 = new Tarea(Tarea1, DateTime.Now);
var Tarea2 = new Tarea(Tarea2, DateTime.Now);
//Las añadimos a dicha lista
ListaDeTareas.Add(Tarea1);
ListaDeTareas.Add(Tarea2);
//Creamos el formateador a binario
var formatter = new BinaryFormatter();
//El stream donde vamos a guardar las tareas
var stream = new FileStream("tareas", FileMode.OpenOrCreate);
//Serializamos nuestra lista y liberamos el stream
formatter.Serialize(stream, ListaDeTareas);
stream.Close();
Y cuando queramos leer las tareas usamos el siguiente código:
//Creamos el stream
var stream = new FileStream("tareas", FileMode.Open);
//Obtenemos la lista del archivo
var Lista = (List<Tarea>)formatter.Deserialize(stream);
stream.Close();
//Recorremos las tareas y las ejecutamos
foreach (var tarea in Lista)
{
tarea.Ejecutar();
}
Debemos importar los siguientes nombres de espacio:
- System.IO
- System.Runtime.Serialization
- System.Runtime.Serialization.Formatters.Binary
Éste código nos generará un código parecido a éste dentro del archivo:
Espero que sea útil.