C# - 列表不为空时触发的事件

时间:2011-05-16 18:24:29

标签: c# events

嘿,我正在创建一个程序,我有几个信息列表。处理列表1中的条目时,它们将从列表1中删除并添加到列表2.当处理列表2中的条目时,它们将被删除并添加到列表3中,依此类推。处理列表时,将从列表中删除处理开始时存在的所有项目。只要程序正在运行,条目就会连续添加到所有列表中,并且不会以可预测的方式。新条目必须相当快地处理。

我认为实现这一目标的最佳方法是让每个列表在添加某些内容时触发事件并执行Action。为了让我的生活更轻松,我创建了一个自定义列表类,它将Action作为构造函数参数,并在触发事件时调用该Action(请参阅代码)。但是,我实现它的方式,即在将某些内容添加到列表时触发事件的方式,在短时间内使用许多新条目的效率非常低。

所以基本上我想知道是否有可能创建一个列表不为空时触发的事件。另外,有没有什么好方法可以确保只要事件已经被解雇并且仍然“活跃”(没有更好的解释),事件就不会再次发射。

如果有任何不清楚的地方,请说明,我会尽力澄清。谢谢!

    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;
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

关于你对重复/重叠激活的关注,一个选项:创建一个处理程序,在处理时“解除”所有处理程序(然后在处理完成后重新连接它们)。

答案 1 :(得分:1)

你看过ObservableCollection吗?它有默认的een CollectionChanged事件,当列表中有更改时会触发该事件。 http://msdn.microsoft.com/en-us/library/ms653375.aspx

答案 2 :(得分:0)

如果我理解正确,可以通过使用ManualResetEvent解决您的问题。当添加项目时,事件将触发并保持活动状态,并且项目继续存在于列表中(即非空)。当列表为空时,您只需重置事件......

ObservableCollection是另一个选项......但是每次添加或删除项目时都会触发CollectionChanged事件,这与您当前手动执行的操作相同......