From 7ce1457c136f13d28adb07fdee7dc06b459bc02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20G=2E=20Aragoneses?= Date: Tue, 24 Sep 2013 01:56:58 +0200 Subject: [PATCH] gtk: Fix a KeyNotFoundException regression in Destroyed event The migration to generic collections [1] caused another regression: a KeyNotFoundException was being thrown (instead of returning null like HashTable did) when using the Destroyed event of the Gtk.Widget class. [1] https://github.com/mono/gtk-sharp/commit/6850b343ca10c1f12294ec864508a8a7153351f5 A particular example of this problem is Banshee's Import Media feature, which was generating the following stacktrace: [1 Debug 23:24:36.898] Starting - Importing Media Marshaling activate signal Exception in Gtk# callback delegate Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2[System.IntPtr,System.Delegate].get_Item (IntPtr key) [0x00000] in :0 at Gtk.Widget.add_Destroyed (System.EventHandler value) [0x00000] in /home/knocte/gtk-sharp/gtk/Widget.cs:333 at Hyena.Widgets.AnimatedWidget..ctor (Gtk.Widget widget, UInt32 duration, Easing easing, Blocking blocking, Boolean horizontal) [0x0004d] in /home/knocte/banshee/src/Hyena/Hyena.Gui/Hyena.Widgets/AnimatedWidget.cs:78 --- gtk/Widget.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gtk/Widget.cs b/gtk/Widget.cs index fef270712..84c840978 100644 --- a/gtk/Widget.cs +++ b/gtk/Widget.cs @@ -330,11 +330,15 @@ namespace Gtk { [GLib.Signal("destroy")] public event EventHandler Destroyed { add { - EventHandler handler = (EventHandler) DestroyHandlers [Handle]; + Delegate delegate_handler; + DestroyHandlers.TryGetValue (Handle, out delegate_handler); + var handler = delegate_handler as EventHandler; DestroyHandlers [Handle] = Delegate.Combine (handler, value); } remove { - EventHandler handler = (EventHandler) DestroyHandlers [Handle]; + Delegate delegate_handler; + DestroyHandlers.TryGetValue (Handle, out delegate_handler); + var handler = delegate_handler as EventHandler; handler = (EventHandler) Delegate.Remove (handler, value); if (handler != null) DestroyHandlers [Handle] = handler;