C# 处理集合内的对象事件

C# 处理集合内的对象事件,c#,events,collections,C#,Events,Collections,如何正确处理集合中对象的事件 示例:我有一个列表,它异步ping多个服务器。如何判断列表中的某个项是否调用了PingCompleted事件?如果我添加/删除Ping对象会怎么样?您需要在每个Ping实例上设置事件处理程序。在事件处理程序中,您可以检查source参数以识别引发事件的Ping对象。 请记住,在使用完该对象以帮助垃圾收集器完成其工作后,请删除处理程序引用。收集比列表继承更好: class PingCollection : Collection<Ping> { pr

如何正确处理集合中对象的事件


示例:我有一个
列表
,它异步ping多个服务器。如何判断列表中的某个项是否调用了PingCompleted事件?如果我添加/删除Ping对象会怎么样?

您需要在每个Ping实例上设置事件处理程序。在事件处理程序中,您可以检查
source
参数以识别引发事件的Ping对象。
请记住,在使用完该对象以帮助垃圾收集器完成其工作后,请删除处理程序引用。

收集比列表继承更好:

class PingCollection : Collection<Ping>
{
    protected override void InsertItem(int index, Ping item)
    {
        ping.PingCompleted += PingCompleted

        base.InsertItem(index, item);
    }

    private void PingCompleted(object sender, EventArgs e)
    {
        // do stuff
    }
}
class PingCollection:Collection
{
受保护的覆盖无效插入项(int索引,Ping项)
{
ping.PingCompleted+=PingCompleted
基本插入项(索引,项目);
}
私有void ping已完成(对象发送方,事件参数e)
{
//做事
}
}
别忘了在删除时取消订阅


(根据丹的建议编辑)

列表。添加
不是虚拟的,因此您必须编写
新的
,而不是
覆盖
。可能最好在内部维护一个
列表
,而不是从中继承,否?
列表
方法不是虚拟的<代码>收藏可能就是你要找的。@Dan,@Ani:谢谢你的更正。但不幸的是,
Collection.Add()
也不是虚拟的,尽管它确实应该是虚拟的。同时,所有其他方法都是。@abatishchev:我认为从
集合
继承的正确方法是重写-
Add
Insert
在内部调用-
SetItem
removietem
,还有
ClearItems
@abatishchev:不过,我确实注意到了您应该做出的改进!而不是使用lambda
ping.PingCompleted+=(发送方,e)=>PingCompleted(发送方,e)
您应该有一个直接指向方法的委托:
ping.PingCompleted+=PingCompleted
这实际上非常重要,否则您将发现无法取消订阅该事件(您无法从
removietem
访问
InsertItem
中lambda表示的相同方法;因此使用
-=
将不起任何作用)。