diff --git a/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs b/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs index 01a0aea..46d3e55 100644 --- a/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs +++ b/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs @@ -52,19 +52,23 @@ public BrowseService (string name, string regtype, string replyDomain, int @inte public void Dispose () { lock (this) { - disposed = true; - DisposeResolver (); + if (!disposed) { + disposed = true; + DisposeResolver (); + } } } private void DisposeResolver () { lock (this) { + IAvahiServiceResolver resolver = this.resolver; + if (resolver != null) { + this.resolver = null; resolver.Failure -= OnResolveFailure; resolver.Found -= OnResolveFound; resolver.Free (); - resolver = null; } } } diff --git a/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs b/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs index 9efe73e..2871525 100644 --- a/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs +++ b/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs @@ -45,17 +45,21 @@ public class ServiceBrowser : IServiceBrowser public void Dispose () { lock (this) { + IAvahiServiceBrowser service_browser = this.service_browser; if (service_browser != null) { + this.service_browser = null; service_browser.ItemNew -= OnItemNew; service_browser.ItemRemove -= OnItemRemove; service_browser.Free (); } - + if (services.Count > 0) { - foreach (BrowseService service in services.Values) { + List services_list = new List (services.Values); + services.Clear (); // Clear first so we no-op if we Dispose() again + + foreach (BrowseService service in services_list) { service.Dispose (); } - services.Clear (); } } } @@ -117,10 +121,11 @@ private void OnItemNew (int @interface, Protocol protocol, string name, string t { lock (this) { BrowseService service = new BrowseService (name, type, domain, @interface, protocol); - - if (services.ContainsKey (name)) { - services[name].Dispose (); + BrowseService to_dispose; + + if (services.TryGetValue (name, out to_dispose)) { services[name] = service; + to_dispose.Dispose (); } else { services.Add (name, service); } @@ -134,10 +139,12 @@ private void OnItemRemove (int @interface, Protocol protocol, string name, strin { lock (this) { BrowseService service = new BrowseService (name, type, domain, @interface, protocol); - - if (services.ContainsKey (name)) { - services[name].Dispose (); + BrowseService to_dispose; + + // handler may be called recursively, so remove service from services before disposing + if (services.TryGetValue (name, out to_dispose)) { services.Remove (name); + to_dispose.Dispose (); } OnServiceRemoved (service);