.net SqlConnection n'étant pas fermé même si dans un {}
S'il vous plaît aider!
Informations de fond
J'ai une application WPF qui accède à un Serveur SQL server 2005 bases de données. La base de données est en cours d'exécution en local sur la machine de l'application est en cours d'exécution sur.
Partout-je utiliser Linq DataContext-je utiliser une aide de { } instruction, et de passer à un résultat d'une fonction qui retourne un objet SqlConnection qui a été ouvert et a une SqlCommand exécutée à l'aide avant de retourner à la DataContext constructeur.. I. e.
//In the application code
using (DataContext db = new DataContext(GetConnection()))
{
... Code
}
où getConnection ressemble à ça (j'ai enlevé le "fluff" de la fonction pour la rendre plus lisible, mais il n'existe aucune fonctionnalité supplémentaire qui est manquant).
//Function which gets an opened connection which is given back to the DataContext constructor
public static System.Data.SqlClient.SqlConnection GetConnection()
{
System.Data.SqlClient.SqlConnection Conn = new System.Data.SqlClient.SqlConnection(/* The connection string */);
if ( Conn != null )
{
try
{
Conn.Open();
}
catch (System.Data.SqlClient.SqlException SDSCSEx)
{
/* Error Handling */
}
using (System.Data.SqlClient.SqlCommand SetCmd = new System.Data.SqlClient.SqlCommand())
{
SetCmd.Connection = Conn;
SetCmd.CommandType = System.Data.CommandType.Text;
string CurrentUserID = System.String.Empty;
SetCmd.CommandText = "DECLARE @B VARBINARY(36); SET @B = CAST('" + CurrentUserID + "' AS VARBINARY(36)); SET CONTEXT_INFO @B";
try
{
SetCmd.ExecuteNonQuery();
}
catch (System.Exception)
{
/* Error Handling */
}
}
return Conn;
}
Je ne pense pas que l'application WPF a aucune incidence sur le problème que j'ai.
La question que je vais avoir
Malgré l'occurrence de SqlConnection étant disposé le long avec le DataContext dans Sql Server Management studio, je peux encore voir des tas de connexions ouvertes avec :
status : 'Sleeping'
command : 'AWAITING COMMAND'
last SQL Transact Command Batch : DECLARE @B VARBINARY(36); SET @B = CAST('GUID' AS VARBINARY(36)); SET CONTEXT_INFO @B
Finalement le pool de connexion est utilisée et l'application ne peut pas continuer.
Donc je ne peux que conclure qu'en quelque sorte, de l'exécution de l'SQLCommand pour définir la Context_Info est en ce sens que la connexion n'est pas se débarrasser une fois le DataContext obtient éliminés.
Quelqu'un peut-il repérer quelque chose d'évident qui aurait un arrêt les connexions à partir de la fermeture et éliminés lorsque le DataContext ils sont utilisés par des sont éliminés?
source d'informationauteur Ash
Vous devez vous connecter pour publier un commentaire.
De MSDN (
DataContext Constructor (IDbConnection)
):Donc, fondamentalement, il semble que vos connexions sont en attente pour GC pour les finaliser avant qu'ils soient libérés. Si vous avez beaucoup de code qui fait cela, on pourrait annuler
Dispose()
dans les données du contexte de la classe partielle, et de fermer la connexion - juste être sûr de document que les données de contexte assume la propriété de la connexion!Personnellement, je serais heureux de lui donner (régulière des données de contexte, w/o le hack ci-dessus) une connexion ouverte tant que j'étais "l'aide" de la connexion (ce qui me permet d'effectuer de multiples opérations) - c'est à dire
La
SqlProvider
utilisé par le LINQDataContext
ne ferme la connexion SQL (parSqlConnectionManager.DisposeConnection
) si il était le seul à l'ouvrir. Si vous donnez déjà ouvertSqlConnection
objet de laDataContext
constructeur, il ne fermera pas pour vous. Ainsi, vous devez écrire:J'ai connu le même problème en utilisant Entity Framework. Mon
ObjectContext
était enroulé autour d'unusing
bloc.Une connexion a été établie lorsque j'ai appelé
SaveChanges()
mais après lausing
déclaration a été hors de portée, j'ai remarqué que SQL Management Studio avait encore un"AWAITING COMMAND"
pour la .NET Client SQL.On dirait que cela a à voir avec le comportement de la ADO.NET fournisseur de pool de connexion est activée par défaut.
De "Utilisant le Regroupement de Connexion avec SQL Server" sur MSDN (l'emphase est mienne):
Aussi
ClearAllPools
etClearPool
semble utile de fermer explicitement toutes les connexions regroupées en cas de besoin.Je pense que la connexion, tout n'est plus référencé, est en attente pour la GC d'en disposer pleinement.
Solution:
Créer votre propre DataContext de la classe qui dérive de l'auto-générés. (renommer la base de l'un de sorte que vous n'avez pas à changer tout autre code).
Dans votre dérivés DataContext - ajout d'une fonction dispose (). - Disposer de la connexion intérieure.
Bien merci pour l'aide les gars, il a été résolu maintenant..
En fait, j'ai pris des éléments de la plupart des réponses ci-dessus et mis en œuvre le DataContext constructeur comme ci-dessus (j'avais déjà surchargé les constructeurs de sorte qu'il n'était pas un grand changement).
La raison pour faire cela plutôt que de certaines des suggestions ci-dessus est que l'accès à
this.Connection
dans la méthode dispose jette un ObjectDisposedException.Et les travaux ci-dessus aussi bien que je l'espérais!
La
Dispose
devrait fermer les connexions, comme MSDN points:J'imagine que votre problème a quelque chose à voir avec
GetContext()
.