tags:

views:

1656

answers:

5

Basic premise:

I have a Room which publishes an event when an Avatar "enters" to all Avatars within the Room. When an Avatar leaves the Room I want it to remove all subscriptions for that room.

How can I best unsubscribe the Avatar from all events in the room before I add the Avatar to a new Room and subscribe to the new Room's events?

The code goes something like this:

class Room
{
   public event EventHandler<EnterRoomEventArgs> AvatarEntersRoom;
   public event EvnetHandler<LeaveRoomEventArgs> AvatarLeavesRoom;
   public event EventHandler<AnotherOfManyEventArgs> AnotherOfManayAvatarEvents;


   public void AddPlayer(Avatar theAvatar)
   {
      AvatarEntersRoom(this, new EnterRoomEventArgs()); 

      AvatarEntersRoom += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);

      AvatarLeavesRoom += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);

      AnotherOfManayAvatarEvents += new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);          

   }

}

class Avatar
{
   public void HandleAvatarEntersRoom(object sender, EnterRoomEventArgs e)
   {
       Log.Write("avatar has entered the room");
   }

   public void HandleAvatarLeaveRoom(object sender, LeaveRoomEventArgs e)
   {
       Log.Write("avatar has left room");
   }

   public void HandleAnotherOfManayAvatarEvents(object sender, AnotherOfManyEventArgs e)
   {
       Log.Write("another avatar event has occurred");
   }
}
+5  A: 

Is there anything wrong with a standard remove?

public void RemovePlayer(Avatar theAvatar) {
 AvatarEntersRoom -= new EventHandler<EnterRoomEventArgs>(theAvatar.HandleAvatarEntersRoom);

}

EDIT

Based on your update it appears that you want code that will remove a particular object from all events on a particular class. There is no realistic way to accomplish this goal. It's often a bit verbose but the best way is to individually add/remove a particular object method combo from every event.

The only way to get close to this functionality is to use reflection. You could reflectively grab all events on your class and then do some magic to find all instances of a class within the event chain. This will only be a partial solution though because it will ignore such things as a lambda expression event handlers.

JaredPar
I don't think the example is complete, the question relates to multiple events. The answer being searched for is a magic "remove any delegates that I have that are attached to any of your events".
AnthonyWJones
@Anthony, the questioner updated the question after my answer. I'll update my response
JaredPar
+3  A: 

Probably the simplest way to accomplish this would be to store all of your subscribed events for an avatar in an ArrayList of delegates to the events.

When the avatar leaves the room, simply loop through the list of delegates performing a standard remove (-=)

Luke
True, but doesn't the framework store the delegates somewhere in a List of some type anyways?
Jimmy
Not sure about that... are you thinking of multicast delegates?
Luke
Yes, in the delegate itself Every delegate inherits from System.MultiCastDelegate, and incldues internal storage fopr an arbitrary number of delegates. When you "register a delegateHandler with a delegate, it just adds the new Hndlr to the list.
Charles Bretana
+5  A: 

Each delegate has a method named GetInvocationList() that returns all the actual delegates that have been registered.. .so, assuming the delegate Type (or event) is named say "MyDelegate", and the instance ( The handler) is named "myDlgHandler", you can write:

    Delegate[] clientList = myDlgHandler.GetInvocationList();
    foreach (Delegate d in clientList)
           myDlgHandler -= (d as MyDelegate);
Charles Bretana
A: 

I had a similar problem. I used reflection to solve it.

Noel Kennedy
A: 

you can run on all the event subscribers with:

_Event.GetInvocationList()

and remove each event handler.

Delegate[] subscribers = myEvent.GetInvocationList();

for(int i = 0; i < subscribers.Length; i++)

{

myEvent -= subscribers[i] as yourDelegateType;

}
Moran