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:

image

Espero que sea útil.

http://eugenioestrada.es/blog

No Comments