C #: evento que se activa cuando una lista no está vacía

Oye, actualmente estoy creando un programa en el que tengo varias listas de información. Cuando se procesan las entradas de la lista 1, se eliminarán de la lista 1 y se agregarán a la lista 2. Cuando se procesen las entradas de la lista 2, se eliminarán y se agregarán a la lista 3 y así sucesivamente. Cuando se procesa una lista, todos los elementos presentes cuando se inició el procesamiento se eliminarán de la lista. Las entradas se agregarán a todas las listas de forma continua mientras el programa se esté ejecutando y de forma no predecible. Las nuevas entradas deberán procesarse con bastante rapidez.

Pensé que la mejor manera de lograr esto es hacer que cada lista active un evento cada vez que se agregue algo y ejecute una acción. Para hacer mi vida más fácil, creé una clase de lista personalizada que toma una Acción como un parámetro de constructor e invoco esa Acción cada vez que se activa el evento (ver código). Sin embargo, la forma en que lo implementé, donde el evento se activa cuando se agrega algo a la lista, es terriblemente ineficiente con muchas entradas nuevas en un corto período de tiempo.

Básicamente, me pregunto si es posible crear eventos que se activen siempre que una lista no esté vacía. Además, ¿hay alguna buena manera de asegurar que un evento no se disparará de nuevo mientras ya se haya disparado y todavía esté "activo" (a falta de una mejor explicación)?

Si algo no está claro, dígalo e intentaré aclararlo. ¡Gracias!

    public class EventDrivenList<T> : List<T>
    {
        private Action action_on_list_change;
        private delegate void ListChangedDelegate(object sender, EventArgs e);
        private event ListChangedDelegate ListChangedEvent;

        private List<T> unprocessed_items; 
        public List<T> List
        {
            get
            {
                lock (unprocessed_items)
                {
                    return unprocessed_items;
                }
            }
        }

        public EventDrivenList(Action action, int size)
        {
            action_on_list_change = action;
            unprocessed_items = new List<T>(size);
            ListChangedEvent += new ListChangedDelegate(OnChangeMethod); 
        }

        public EventDrivenList(Action action)
        {
            action_on_list_change = action;
            unprocessed_items = new List<T>();
            ListChangedEvent += new ListChangedDelegate(OnChangeMethod); 
        }

        ~EventDrivenList()
        {
            ListChangedEvent -= new ListChangedDelegate(OnChangeMethod);
        }

        private void OnChange(EventArgs e)
        {
            if (ListChangedEvent != null)
                ListChangedEvent(this, e);
        }

        private void OnChangeMethod(object sender, EventArgs e)
        {   
             action_on_list_change.Invoke();            
        }

        new public void Add(T item)
        {
            lock (unprocessed_items)
            {
                unprocessed_items.Add(item);
            }
            OnChange(EventArgs.Empty);
        }

        new public void Remove(T item)
        {
            lock (unprocessed_items)
            {
                unprocessed_items.Remove(item);
            }
        }

        new public int Count()
        {
            lock (unprocessed_items)
            {
                return unprocessed_items.Count;
            }
        }
    }

preguntado el 16 de mayo de 11 a las 18:05

Tu finalizador y la mayoría de tus bloqueos son inútiles. -

Se cambió a ArrayList, se eliminó el deconstructor y los bloqueos inútiles. Muchas gracias. -

ArrayList es aún peor. Utilizar Collection<T>. -

Ay, bueno, aprender fallando. Gracias de nuevo -

3 Respuestas

Con respecto a su preocupación acerca de los disparos duplicados / superpuestos, una opción: cree un controlador que "desconecte" todos los controladores mientras está manejando (y luego vuelva a conectarlos cuando haya terminado de manejarlos).

contestado el 16 de mayo de 11 a las 22:05

¿Ha echado un vistazo a ObservableCollection? Tiene un evento CollectionChanged predeterminado que se activa cuando algo cambia en la lista. http://msdn.microsoft.com/en-us/library/ms653375.aspx

contestado el 16 de mayo de 11 a las 22:05

Lástima que no lo encontré más temprano, porque básicamente hace lo mismo que he codificado, y mucho más. Bien podría reemplazar la mayor parte de mi código ahora. Salud. - Henrik

Si entendí esto correctamente, su problema podría resolverse usando un ManualResetEvent. El evento se dispararía y permanecería activo cuando se agrega un elemento, y los elementos continúan estando presentes en la lista (es decir, no vacíos). Cuando la lista esté vacía, simplemente puede restablecer el evento ...

Un ObservableCollection es otra opción ... sin embargo, esto dispararía un evento CollectionChanged cada vez que se agrega o elimina un elemento, que sería lo mismo que lo que está haciendo actualmente manualmente ...

contestado el 16 de mayo de 11 a las 22:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.