2012-02-24 3 views
25

Certains articles indiquent que les appels de bases de données asynchrones sont une mauvaise idée dans .NET.Tout inconvénient d'utiliser ExecuteReaderAsync à partir de C# AsyncCTP

C# Async CTP, il y a une extension System.Data.SqlClient.SqlCommand appelé ExecuteReaderAsync. J'ai quelques opérations comme ci-dessous sur mon code existant:

var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString; 

using (var conn = new SqlConnection(connectionString)) { 
    using (var cmd = new SqlCommand()) { 

     cmd.Connection = conn; 
     cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount"; 
     cmd.CommandType = System.Data.CommandType.StoredProcedure; 

     conn.Open(); 

     var reader = cmd.ExecuteReader(); 
     while (reader.Read()) { 

      //do the reading 

     } 

     conn.Close(); 
    } 
} 

Il ya plusieurs opérations comme ceci sur mon code. Donc, j'ai des réflexions sur la conversion de ceux-ci en asynchrones. Mais d'un autre côté, je ne vois pas beaucoup d'attraction sur cette approche là-bas (peut-être que je ne regarde pas la bonne direction, qui sait!).

Alors, y a-t-il des inconvénients à utiliser ce nouveau modèle de programmation asynchrone?

Edit:

En supposant que je Refactor le code comme ci-dessous:

public async Task<IEnumerable<Foo>> GetDataAsync() { 

    List<Foo> foos = new List<Foo>(); 

    var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString; 

    using (var conn = new SqlConnection(connectionString)) { 
     using (var cmd = new SqlCommand()) { 

      cmd.Connection = conn; 
      cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount"; 
      cmd.CommandType = System.Data.CommandType.StoredProcedure; 

      conn.Open(); 

      var reader = await cmd.ExecuteReaderAsync(); 
      while (reader.Read()) { 

       //do the reading 
       //create foos 

      } 

      conn.Close(); 
     } 
    } 

    return foos; 

} 

Pour autant que je comprends le mot-clé await, il convertit le code, ce qui est après, comme suite. En outre, lorsqu'il frappe le mot-clé await, il renvoie immédiatement à son appelant, quel que soit le statut de l'opération. Quand il se termine, il revient et déclenche le code de continuation.

C'est ce que j'ai en tête.

+0

Bien que la réponse acceptée soit parfaite, j'aimerais ajouter mon exemple. Dans mon site Web, j'ai fait toutes les méthodes d'action comme Task et fait tous les appels db async. Le site a vraiment commencé à se charger plus rapidement –

Répondre

50

Je ne suis pas d'accord avec Ricka à ce sujet. Les commandes DB asynchrones ne sont pas seulement bonnes, elles sont essentielles pour atteindre l'échelle, le débit et la latence. Son objection au sujet du temps d'accélération du pool de threads s'applique uniquement à un serveur Web qui connaît des volumes de trafic faibles.

Dans une situation de fort trafic (qui est la seule qui compte), le pool de threads n'aura pas à attendre l '«injection» de nouveaux threads. L'exécution asynchrone des commandes SQL est importante non seulement du point de vue de l'intégrité des requêtes/threads du serveur Web, mais aussi du point de vue de la durée de vie totale de la requête: les appels DB non corrélés peuvent être effectués en parallèle. Cela seul entraîne généralement des améliorations spectaculaires dans la latence de la requête HTTP telle que vécue par l'utilisateur. En d'autres termes, vos pages se chargent plus rapidement. Un conseil: la commande SQL n'est pas réellement asynchrone tant que vous n'avez pas activé Asynchronous Processing=true sur la chaîne de connexion. Bien que cela ne soit pas défini (et par défaut n'est pas, Edit:. Commence avec .NET Framework 4.5 < Asynchronous Processing is no longer required) votre « asyncronous » appelle à BeginExecuteReader ne sont qu'un trompe-l'œil, l'appel va lancer un fil et de bloquer que fil. Lorsque le vrai traitement asynchrone est activé dans la chaîne de connexion alors l'appel est vraiment asynchrone et le rappel est basé sur l'achèvement d'E/S. Un mot d'avertissement: une commande SQL async se termine dès que le résultat premier retourne au client, et les messages d'information comptent comme résultat.

create procedure usp_DetailsTagsGetAllFromApprovedPropsWithCount 
as 
begin 
print 'Hello'; 
select complex query; 
end 

Vous avez perdu tous les avantages de l'async. Le print crée un résultat qui est renvoyé au client, ce qui termine la commande async et l'exécution sur le client reprend et continue avec 'reader.Read()'. Maintenant que va bloquer jusqu'à ce que la requête complexe commence à produire des résultats. Vous demandez 'qui met print dans la procédure?' mais le print peut être déguisé en quelque chose d'autre, peut-être quelque chose d'aussi innocent que INSERT qui exécute sans d'abord en émettant un SET NOCOUNT ON.

+0

* "La commande n'est pas vraiment asynchrone tant que vous n'avez pas activé le traitement asynchrone = true sur la chaîne de connexion." * Est-ce toujours applicable si j'utilise le nouveau modèle de programmation asynchrone? – tugberk

+2

Bon seigneur qui prend des décisions de conception comme ça? Ces pièges sont absurdes. –

+0

@tugberk: Je suis à peu près sûr que 'ExecuteReaderAsync' n'est rien d'autre qu'un wrapper autour de' BeginExecuteReader'/'EndExecuteReader', donc la condition de la chaîne de connexion s'applique aussi. –

0

Je remarque que la question suivante n'a pas répondu:

Alors, est-il des inconvénients de l'utilisation de ce nouveau modèle de programmation async ici?

Le inconvénient qui est très minime (cpu/mémoire mineure mineure afaik), est que parce qu'il ya la possibilité d'une exécution de code après une déclaration await peut exécuter sur un thread séparé, un state-machine existe pour stocker l'état du thread en cours d'exécution afin que la poursuite du travail puisse être gérée sur un autre thread. Vous pouvez en savoir plus sur le await/async statemachine on Dixin's Blog - Understanding C# async/await (1) Compilation.

Questions connexes