2014-07-15 6 views
0

Salut à tous et merci d'avance. J'essaie de corriger une méthode qui insère des informations dans une table de base de données. Actuellement, il connaît des dépassements de délai car il s'exécute dans une boucle while qui prend trop de temps pour traiter tout le contenu. Bien que je sache que je pourrais juste augmenter le délai de commande, je ne pense pas que cela résout le problème parce que je pense que c'est le code. Mais je ne suis pas certain de la solution correcte. J'ai accès à Dapper et je me demande s'il serait plus efficace de faire une méthode qui passe les variables nécessaires et exécute juste une simple déclaration rapide pour ce groupe puis passe à la suivante? Ou est-ce juste perpétuer ce qui est juste d'une manière différente? Dois-je déplacer cela hors du code et sur le serveur pour de meilleures performances?Timeout expiré - Session - Comment réparer

UPDATE message d'erreur complète:

Exception de type 'System.Web.HttpUnhandledException' a été levée.
fichier: c: \ WINDOWS \ Microsoft.NET \ Framework \ v4.0.30319 \ Temporary ASP.NET Files \ 6caa4c91 \ 19b853c6 \ App_Web_o3102kpb.9.cs
Méthode: ProcessRequest Numéro de ligne: 0
Exception interne: {Délai d'attente expiré. Le délai d'expiration s'est écoulé avant la fin de l'opération ou le serveur ne répond pas.
Fichier: z: \ inetpub \ wwwroot \ SessionTransfer.aspx.cs
Méthode: AddSessionToDatabase Numéro de ligne: 94
Le délai d'expiration a expiré. Le délai d'expiration s'est écoulé avant la fin de l'opération ou le serveur ne répond pas.
fichier: z: \ inetpub \ wwwroot \ SessionTransfer.aspx.cs Méthode: Page_Load Numéro de ligne: 33}

Voici le code original:

 SqlConnection con = new SqlConnection(connectionString); 
 SqlCommand cmd = new SqlCommand(); 
     con.Open(); 
     cmd.Connection = con; 
     int i = 0; 
     string strSql, guid = GetGuid(); 

     string temp = ""; 

     while (i < Session.Contents.Count) 
     { 
      if (Session.Contents[i] == null) 
       temp = ""; 
      else { 
       if ((Session.Contents[i].ToString().Trim().Length) > 0) 
        temp = Session.Contents[i].ToString().Replace("'", "''"); 
       else 
        temp = ""; 
      } 

      strSql = "INSERT INTO SessionTable (GUID, SessionKey, SessionValue) " + 
        "VALUES ('" + guid + "', '" + Session.Contents.Keys[i].ToString() + "', '" + temp + "')"; 
      cmd.CommandText = strSql; 
      cmd.ExecuteNonQuery(); 
      i++; 
     } 

     con.Close(); 
     cmd.Dispose(); 
     con.Dispose(); 

     return guid; 

MISE À JOUR - SOLUTION FINALE:

 var SessionList = new List<Session>(); 
 while (i < Session.Contents.Count) 
     { 
      string temp = ""; 
      if (Session.Contents[i] == null) 
       temp = ""; 
      else 
      { 
       temp = (Session.Contents[i].ToString().Trim().Length) > 0 ? Session.Contents[i].ToString().Replace("'", "''") : ""; 
      } 
      var s = new Session 
      { 
       TempGuid = guidTemp, 
       Contents = Session.Contents[i] != null ? Session.Contents[i].ToString() : null, 
       Temp = temp 
      }; 
      SessionList.Add(s); 

      i++; 
     } 
     mySession = SerializationUtilities.SerializeObjectToXML(SessionList); 

     using (var con = new SqlConnection()) 
     { 
      con.ExecuteHGW("Transfer", new { mySession }, commandType: CommandType.StoredProcedure); 
     } 

ensuite sur le côté SQL je viens de mettre le XML dans une table et a fait une déclaration unique d'insertion sur la table, le temps est nettement améliorée.

+0

Première question est le message de délai d'attente est que bouillonnant réellement de votre SQL ou du temps nécessaire pour exécuter la requête? Est-il possible d'inclure le message d'erreur réel? Combien de fois cette boucle traverse-t-elle? –

+0

J'ai inclus le message d'erreur complet, dans cet exemple particulier le Session.Contents.Count est 38. J'ai d'autres erreurs où le nombre a varié 39, 37, etc. –

+0

On dirait qu'un client Web attend une réponse de le serveur et le délai d'expiration. Est-il possible de lancer votre boucle while dans un thread différent et de renvoyer le Guid tout de suite? – MisterXero

Répondre

0

Je voudrais vous suggérer des améliorations 2:

  1. dans la boucle que vous exécutez les instructions d'insertion, un par un contre db. Il faut beaucoup de temps pour ouvrir la connexion à db puis envoyer la requête, l'exécuter et retourner le résultat. Il est préférable de les traiter par lots. Donc rassemblez comme 10.000 de telles instructions d'insertion, construisez l'instuction entière avec StringBuilder et exécutez-le contre DB en une seule fois. Cela va vraiment augmenter la vitesse de votre application. Quantité d'instructions d'insertion dans un lot, vous devez choisir vous-même sur la base des tests du système.
  2. Si, après application 1) laisser entendre le problème avec délai d'attente se produit encore je suggère 2 solutions possibles:

    a). N'envoyez pas tous les éléments à traiter en même temps que db au service Web mais, comme précédemment, chargez-les (appliquez le second batching). Par exemple, envoyez au service Web 50 000 éléments à insérer, puis attendez la confirmation du service Web, puis passez au lot suivant.Le grand avantage est que vous pouvez montrer à l'utilisateur facilement la barre de progression lui indiquant l'état de fonctionnement actuel.

    b). envoyer tous les éléments à traiter en même temps sur db mais n'attendez pas le résultat. Dans votre application, il suffit de montrer que les éléments sont traités et chaque 10 s envoyer à la demande de service Web pour demander si le travail est terminé. Quand c'est fini, signalez-le à l'utilisateur.

+0

Entre MisterXero et mr100 la solution que je suis allé avec plus étroitement liée à l'idée présentée ici, donc je vais marquer ce correct mais éditer ma question avec ce que ma solution finale ressemblait. –