[Mono-bugs] [Bug 74607][Wis] New - Delegate InvocationList not correctly updated when events are unhooked

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Thu, 14 Apr 2005 13:14:07 -0400 (EDT)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by larsde@key2network.com.

http://bugzilla.ximian.com/show_bug.cgi?id=74607

--- shadow/74607	2005-04-14 13:14:07.000000000 -0400
+++ shadow/74607.tmp.6912	2005-04-14 13:14:07.000000000 -0400
@@ -0,0 +1,113 @@
+Bug#: 74607
+Product: Mono: Runtime
+Version: 1.1
+OS: 
+OS Details: Ubuntu Hoary with Mono from SVN (20050413)
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Wishlist
+Component: misc
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: larsde@key2network.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Delegate InvocationList not correctly updated when events are unhooked
+
+Please fill in this template when reporting a bug, unless you know what you
+are doing.
+Description of Problem:
+
+I add some event-listeners to an event, and then remove one of them. Events
+now fire correctly, but invocationlist is incorrect. This makes events
+serialize incorrectly.
+
+
+Steps to reproduce the problem:
+1. Compile and run attached program
+2. 
+3. 
+
+Actual Results:
+
+InvocationList is fired as expected, but size and contents are incorrect,
+leading to erraneous serialization.
+
+Expected Results:
+
+Invocationlist be of correct size and eventlisteners unhooked from event
+not be serialized.
+
+How often does this happen? 
+
+Every time.
+
+Additional Information:
+
+Here is test program:
+
+using System;
+using System.Reflection;
+
+class MainClass
+{
+	public class Listener {
+		string label;
+		public Listener(string label) {
+			this.label = label;
+		}
+	
+		public void Listen(object sender, EventArgs e) {
+			System.Console.WriteLine("  " + label + ":Got event");
+		}	
+	}
+	
+	public class Source {
+		public event EventHandler Event;	
+		public void Report() {
+			if (Event != null) {
+				System.Console.WriteLine("  Size of invocationlist: {0}",
+Event.GetInvocationList().Length);
+			} else System.Console.WriteLine("  Empty invocationlist");
+		}
+		
+		public void Fire() {
+			if (Event != null) Event(this, new EventArgs());
+		}
+	}
+
+	public static void Main(string[] args)
+	{
+		Source s = new Source();
+		Listener l = new Listener("one");
+		Listener l2 = new Listener("two");
+				
+		// Get source eventinfo
+		EventInfo e = (EventInfo)s.GetType().GetMember("Event")[0];
+		
+		s.Event += l.Listen;
+
+		Delegate del = Delegate.CreateDelegate(typeof(EventHandler), l2,"Listen");
+		e.AddEventHandler(s, del);
+
+		System.Console.WriteLine("Should have an invocationlist of two");
+		s.Report();
+		
+		System.Console.WriteLine("Both listeners should receive events");	
+		s.Fire();
+		
+		e.RemoveEventHandler(s, del);
+		
+		System.Console.WriteLine("Size of invocationlist should be 1");
+		s.Report();
+		
+		System.Console.WriteLine("!!! Seems it is two");
+		System.Console.WriteLine("Only listener one should get an event");
+		s.Fire();
+		
+		System.Console.WriteLine("Works correctly, but delegate serializes
+incorrectly");
+	}
+}