diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
index 1ee4cba196..bdecce6fc1 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
@@ -474,5 +474,10 @@ protected virtual DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal i
abstract internal bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from);
abstract internal void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to);
+
+ virtual internal void Unload()
+ {
+ _pruningTimer.Dispose();
+ }
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index 3e7db7d945..b7bbba8abc 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -309,6 +309,8 @@
+
+
@@ -778,7 +780,7 @@
-
+
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs
new file mode 100644
index 0000000000..7338b8d4d2
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.AssemblyLoadContext.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Reflection;
+using System.Runtime.Loader;
+
+namespace Microsoft.Data.SqlClient
+{
+ sealed internal partial class SqlConnectionFactory
+ {
+ partial void SubscribeToAssemblyLoadContextUnload()
+ {
+ AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += SqlConnectionFactoryAssemblyLoadContext_Unloading;
+ }
+
+ private void SqlConnectionFactoryAssemblyLoadContext_Unloading(AssemblyLoadContext obj)
+ {
+ Unload(obj, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
index 597a140a76..93450aec7b 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionFactory.cs
@@ -11,12 +11,15 @@
namespace Microsoft.Data.SqlClient
{
- sealed internal class SqlConnectionFactory : DbConnectionFactory
+ sealed internal partial class SqlConnectionFactory : DbConnectionFactory
{
private const string _metaDataXml = "MetaDataXml";
- private SqlConnectionFactory() : base() { }
+ private SqlConnectionFactory() : base()
+ {
+ SubscribeToAssemblyLoadContextUnload();
+ }
public static readonly SqlConnectionFactory SingletonInstance = new SqlConnectionFactory();
@@ -306,6 +309,20 @@ protected override DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal
internalConnection.ServerVersion,
internalConnection.ServerVersion);
}
+
+ private void Unload(object sender, EventArgs e)
+ {
+ try
+ {
+ Unload();
+ }
+ finally
+ {
+ ClearAllPools();
+ }
+ }
+
+ partial void SubscribeToAssemblyLoadContextUnload();
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AppDomain.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AppDomain.cs
index 959122bf1c..d82a9fc8fa 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AppDomain.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AppDomain.cs
@@ -11,28 +11,10 @@ namespace Microsoft.Data.SqlClient
// for example, some mobile profiles on mono
partial class SqlDependencyPerAppDomainDispatcher
{
- private void SubscribeToAppDomainUnload()
+ partial void SubscribeToAppDomainUnload()
{
// If rude abort - we'll leak. This is acceptable for now.
AppDomain.CurrentDomain.DomainUnload += new EventHandler(UnloadEventHandler);
}
-
- private void UnloadEventHandler(object sender, EventArgs e)
- {
- long scopeID = SqlClientEventSource.Log.TryNotificationScopeEnterEvent("SqlDependencyPerAppDomainDispatcher.UnloadEventHandler | DEP | Object Id {0}", ObjectID);
- try
- {
- // Make non-blocking call to ProcessDispatcher to ThreadPool.QueueUserWorkItem to complete
- // stopping of all start calls in this AppDomain. For containers shared among various AppDomains,
- // this will just be a ref-count subtract. For non-shared containers, we will close the container
- // and clean-up.
- var dispatcher = SqlDependency.ProcessDispatcher;
- dispatcher?.QueueAppDomainUnloading(SqlDependency.AppDomainKey);
- }
- finally
- {
- SqlClientEventSource.Log.TryNotificationScopeLeaveEvent(scopeID);
- }
- }
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs
new file mode 100644
index 0000000000..47f62fc5ac
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.AssemblyLoadContext.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Reflection;
+using System.Runtime.Loader;
+
+namespace Microsoft.Data.SqlClient
+{
+ // these members were moved to a separate file in order
+ // to be able to skip them on platforms where AssemblyLoadContext members are not supported
+ // for example, netstandard
+ partial class SqlDependencyPerAppDomainDispatcher
+ {
+ partial void SubscribeToAssemblyLoadContextUnload()
+ {
+ AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += SqlDependencyPerAppDomainDispatcher_Unloading;
+ }
+
+ private void SqlDependencyPerAppDomainDispatcher_Unloading(AssemblyLoadContext obj)
+ {
+ UnloadEventHandler(null, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs
index e4f2a4446a..15f2b573e2 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDependencyUtils.cs
@@ -94,6 +94,29 @@ private SqlDependencyPerAppDomainDispatcher()
Timeout.Infinite);
SubscribeToAppDomainUnload();
+ SubscribeToAssemblyLoadContextUnload();
+ }
+ finally
+ {
+ SqlClientEventSource.Log.TryNotificationScopeLeaveEvent(scopeID);
+ }
+ }
+
+ partial void SubscribeToAppDomainUnload();
+
+ partial void SubscribeToAssemblyLoadContextUnload();
+
+ private void UnloadEventHandler(object sender, EventArgs e)
+ {
+ long scopeID = SqlClientEventSource.Log.TryNotificationScopeEnterEvent("SqlDependencyPerAppDomainDispatcher.UnloadEventHandler | DEP | Object Id {0}", ObjectID);
+ try
+ {
+ // Make non-blocking call to ProcessDispatcher to ThreadPool.QueueUserWorkItem to complete
+ // stopping of all start calls in this AppDomain. For containers shared among various AppDomains,
+ // this will just be a ref-count subtract. For non-shared containers, we will close the container
+ // and clean-up.
+ var dispatcher = SqlDependency.ProcessDispatcher;
+ dispatcher?.QueueAppDomainUnloading(SqlDependency.AppDomainKey);
}
finally
{
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.NetCoreApp.cs
index ec3b6549b3..8035b460db 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.NetCoreApp.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDiagnosticListener.NetCoreApp.cs
@@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.Loader;
namespace Microsoft.Data.SqlClient
{
@@ -10,6 +12,12 @@ internal sealed class SqlDiagnosticListener : DiagnosticListener
{
public SqlDiagnosticListener(string name) : base(name)
{
+ AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).Unloading += SqlDiagnosticListener_Unloading;
+ }
+
+ private void SqlDiagnosticListener_Unloading(AssemblyLoadContext obj)
+ {
+ Dispose();
}
}
}