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
+}