diff --git a/CHANGELOG.md b/CHANGELOG.md index f7adb657..661c633c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## Version 2.3.0-beta2 +- [Fixed race condition on dispose to close #651](https://github.com/Microsoft/ApplicationInsights-aspnetcore/pull/652) -Removed DomainNameRoleInstanceTelemetryInitializer as it is deprecated. -Reuse AzureWebAppRoleEnvironmentTelemetryInitializer from WindowsServer repo instead of outdated implementation in this repo. - Updated Web/Base SDK version dependency to 2.6.0-beta4 diff --git a/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/ApplicationInsightsInitializer.cs b/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/ApplicationInsightsInitializer.cs index fe205047..5d4d9b96 100644 --- a/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/ApplicationInsightsInitializer.cs +++ b/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/ApplicationInsightsInitializer.cs @@ -2,18 +2,20 @@ namespace Microsoft.ApplicationInsights.AspNetCore { using System; using System.Collections.Generic; + using System.Collections.Concurrent; using System.Diagnostics; using Extensions; using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; + using System.Threading; /// /// Class used to initialize Application Insight diagnostic listeners. /// internal class ApplicationInsightsInitializer : IObserver, IDisposable { - private readonly List subscriptions; + private ConcurrentBag subscriptions; private readonly IEnumerable diagnosticListeners; /// @@ -26,7 +28,7 @@ public ApplicationInsightsInitializer( IServiceProvider serviceProvider) { this.diagnosticListeners = diagnosticListeners; - this.subscriptions = new List(); + this.subscriptions = new ConcurrentBag(); // Add default logger factory for debug mode only if enabled and instrumentation key not set if (options.Value.EnableDebugLogger && string.IsNullOrEmpty(options.Value.InstrumentationKey)) @@ -48,11 +50,17 @@ public void Start() /// void IObserver.OnNext(DiagnosticListener value) { + var subs = Volatile.Read(ref this.subscriptions); + if (subs is null) + { + return; + } + foreach (var applicationInsightDiagnosticListener in this.diagnosticListeners) { if (applicationInsightDiagnosticListener.ListenerName == value.Name) { - this.subscriptions.Add(value.SubscribeWithAdapter(applicationInsightDiagnosticListener)); + subs.Add(value.SubscribeWithAdapter(applicationInsightDiagnosticListener)); } } } @@ -75,13 +83,21 @@ public void Dispose() protected virtual void Dispose(bool disposing) { - if (disposing) + if (!disposing) { - foreach (var subscription in this.subscriptions) - { - subscription.Dispose(); - } + return; + } + + var subs = Interlocked.Exchange(ref this.subscriptions, null); + if (subs is null) + { + return; + } + + foreach (var subscription in subs) + { + subscription.Dispose(); } } } -} \ No newline at end of file +}