views:

59

answers:

3

How do I properly handle the events of objects inside a collection?

Example: I have a List<Ping> which asynchronously pings a number of servers. How can I tell if one of the items in the List have called the PingCompleted event? What if I add/remove Ping objects?

+1  A: 

You need to set the event handler on each Ping instance. Inside the event handler you can inspect the source parameter to identify the Ping object that raised the event. Remember to remove the handler reference once you are finished using the object to help the Garbage Collector do its job.

Xint0
A: 

Please check this link it may help u.

programmer4programming
+1  A: 

Collection is rather better than List for inheritance:

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

And don't forget to unsubscribe on remove.

(Edited to lead Dan's suggestion)

abatishchev
`List<T>.Add` isn't virtual, so you'd have to write `new` instead of `override`. Probably better to maintain a `List<Ping>` internally rather than inherit from it, no?
Dan Tao
`List<T>` methods are not virtual. `Collection<T>` is probably what you're looking for.
Ani
@Dan, @Ani: Thanks for the correction. But unfortunately `Collection<T>.Add()` also is not virtual though definitely should be. Meanwhile all other methods - are.
abatishchev
@abatishchev: I believe the correct way to inherit from `Collection<T>` is to override [`InsertItem`](http://msdn.microsoft.com/en-us/library/ms132412.aspx)--which is called by `Add` and `Insert` internally--and also to override `SetItem`, `RemoveItem`, and `ClearItems`.
Dan Tao
@Dan: Great suggestion, thanks! Edited. Know now, will use in the future. P.S. If the downvote is your, what else can be improved to avoid it?
abatishchev
@abatishchev: Sorry, the downvote isn't from me :(
Dan Tao
@abatishchev: I *did* just notice an improvement you should make, though! Instead of using the lambda `ping.PingCompleted += (sender, e) => PingCompleted(sender, e);` you should just have a delegate pointing straight to the method: `ping.PingCompleted += PingCompleted;` This is actually **very important** as otherwise you'll find you cannot unsubscribe from the event (you cannot access the same method represented by the lambda in `InsertItem` from `RemoveItem`; thus using `-=` would do nothing).
Dan Tao
@Dan: Great! Thanks! Edited.
abatishchev
Thanks guys, much appreciated :D
GaiusSensei