2017-10-04 8 views
0

Je crée une application (c'est un serveur) qui utilise un socket pour recevoir des données de différents clients (un serveur de discussion) et qui a accès à une base de données (Microsoft SQL Server).Devrais-je laisser ma SqlConnection ouverte lorsque je traite du code asynchrone via APM?

La boucle de mise à jour du serveur ressemble à quelque chose comme ceci:

void UpdateLoop() 
{ 
    while(true) 
    { 
     ReceiveData(); 
     ProcessData(); 
    } 
} 

Chaque fois que je reçois une donnée (une chaîne) d'un client, ces données seront enregistrées dans la base de données, en utilisant une procédure stockée. Comme il est seul thread et je veux éviter les opérations de blocage, je choisi d'utiliser le modèle de programmation asynchrone (APM):

void ProcessData() 
{ 
    var command = new SqlCommand("stored_procedure_name", _connection); 
    command.CommandType = CommandType.StoredProcedure; 

    command.BeginExecuteNonQuery(CommandCallback, command); 
    /*at this point, we return to the UpdateLoop method and 
     the command keeps running asynchronously, avoid blocking 
     the whole thread and processing other requests.*/ 
} 

void CommandCallback(IAsyncResult ar) 
{ 
    var command = (SqlCommand)ar.AsyncState; 
    command.EndExecuteNonQuery(ar); 
} 

Comme vous pouvez le voir ci-dessus, la variable _connection représente la classe SqlConnection, qui détient la connexion à la base de données. J'ouvre la connexion au début de l'application et je la ferme uniquement à la fin de l'application.

J'ai lu qu'il vaut mieux (et une bonne pratique de codage) pour ouvrir la connexion uniquement en cas de besoin et de disposer immédiatement après l'utilisation, avec le using, comme ceci:

using(var connection = new SqlConnection("...")) 
{ 
    //create the command and execute it (synchronously) 
} 

Mais je (pense) ne peut pas utiliser le en utilisant déclaration avec mon code actuel, car il doit être asynchrone.

Est-il possible de laisser la connexion sql ouverte tout le temps? Si non, quelle est la meilleure solution pour ce cas?

+0

Ce n'est généralement pas un gros problème de laisser la connexion établie, tant qu'elle reste inactive et ne laisse pas une transaction ouverte. Un coût non nul est associé à l'établissement d'une connexion à la base de données. Par conséquent, si vous effectuez un trafic important, la fermeture et la réouverture des connexions milliers de fois par minute commenceront à être remarquables. Dans ce scénario, il est décidément préférable de laisser les connexions établies. – Xedni

+0

Débarrassez-vous de vos ressources dès que vous en avez fini avec elles. Sql Connection pool prendra soin de prioriser pour vous dès que vous avez besoin de rétablir une connexion. – Kyle

Répondre

0

La règle est claire: ouvrir la connexion et la fermer dès que possible;) bien sûr en un mot. J'ai fait une conversation assez similaire à la vôtre récemment et je ne me soucie pas de la connexion. Je l'ouvre quand j'en ai besoin et je le ferme après avoir obtenu des données. La raison principale est que lorsque l'application ouvre la connexion en fait, elle ne l'ouvre pas vraiment. Étrange? Pas vraiment. Il y a quelque chose comme la piscine de connexion où sont coulpe des connexions prêtes à l'emploi. Connexion physiquement ouverture à db prend beaucoup de temps donc la piscine mentionnée a été "inventée". Si votre discussion est de plus en plus populaire, essayez de changer de Websockets.

+0

Merci pour la réponse! Mais comment puis-je fermer la connexion dans mon cas, car il est asynchrone (APM)? Dois-je fermer la connexion sur la méthode CommandCallback? Et si des milliers de demandes étaient traitées en même temps? – hendoe