IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Timeout durant connexion sql server trop long (avec mauvais nom de serveur). [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Webmaster
    Inscrit en
    Octobre 2014
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Antilles Néerlandaises

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Octobre 2014
    Messages : 73
    Par défaut Timeout durant connexion sql server trop long (avec mauvais nom de serveur).
    Bonjour à tous,

    J'ai un problème pour appliquer un Time-out de connexion. Je me connecte trois fois sur un serveur et j'aimerais que si le nom de serveur est erroné le pc ne "mouline" pas trop sachant que ma base sera en locale donc c'est censé prendre moins de quelques secondes si le nom de serveur est correcte. Quand le nom de serveur est mauvais, la 1ère ouverture de connexion prend 30 secondes environ systématiquement et après le time-out n'est pas vraiment non plus respecté bien que dans la console s'affiche la bonne valeur de Timeout quand je tape ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    oConnection.ConnectionTimeout

    ci-dessous la code de ma connexion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
            public string RecupValeurUniqueOK(string NomServeur, string NomBase, bool Auth, string user, string password, string querySQL, string Timeout = "5")
            {
                string connexionString;
                string valeurUnique;
     
                if (Auth == true)
                {
     
                    connexionString = "Data Source=" + NomServeur + ";Integrated Security=True;Initial Catalog=" + NomBase + ";Connection Timeout=" + Timeout;
     
                }
                else
                {
                    connexionString = "Data Source=" + NomServeur + ";Initial Catalog=" + NomBase + ";User ID=" + user + ";Password=" + password + ";Connection Timeout=" + Timeout;
                }
     
                    try
                    {
                    using (SqlConnection oConnection = new SqlConnection(connexionString))
                    {
                        oConnection.Open();
     
                        using (SqlCommand oCommand = new SqlCommand(querySQL, oConnection))
                        {
                            oCommand.CommandTimeout = 5;
                            valeurUnique = oCommand.ExecuteScalar().ToString();
                            oConnection.Close();
                            return valeurUnique;
                        }
                    }
                    }
                    catch
                    {
                        Console.WriteLine("Erreur de connexion");
    					return "0";
                    }
            }

    Et là le code que je lance lié à la méthode plus haut.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
            private void RetrouverNumeroPieceTest()
            {
                ConnexionSQL beginSQL = new ConnexionSQL();
                int compteur = 0;
                int m1 = 0;
                int m2 = 0;
                int m3 = 0;
                string result1 = "0";
                string[] Arr2 = new string[] { "fgdfgdfsg", "NomBase", "true", "User", "Password", "False", "False", "8" };
     
                string query = FileStore.Resource1.UNION_ACH_VTE_STK_NUMPIECE;
                query = query.Replace("NumeroDoc", txtBoxEan.Text);
     
                Console.WriteLine("Valeur du Timeout : " + Arr2[7]);
                result1 = beginSQL.RecupValeurUniqueOK(Arr2[0], Arr2[1], Convert.ToBoolean(Arr2[2]), Arr2[3], Arr2[4], "SELECT COUNT(*) from (" + query + ") as NB", Arr2[7]);
                compteur += Convert.ToInt16(result1); m1 += Convert.ToInt16(result1);
     
                result1 = beginSQL.RecupValeurUniqueOK(Arr2[0], Arr2[1], Convert.ToBoolean(Arr2[2]), Arr2[3], Arr2[4], "SELECT COUNT(*) from (" + query + ") as NB", Arr2[7]);
                compteur += Convert.ToInt16(result1); m2 += Convert.ToInt16(result1);
     
                result1 = beginSQL.RecupValeurUniqueOK(Arr2[0], Arr2[1], Convert.ToBoolean(Arr2[2]), Arr2[3], Arr2[4], "SELECT COUNT(*) from (" + query + ") as NB", Arr2[7]); ;
                compteur += Convert.ToInt16(result1); m3 += Convert.ToInt16(result1);
     
                MessageBox.Show("Compte rendu : Chez m1 :" + m1 + ". Chez m2 :" + m2 + ". Chez m3: " + m3 + ". Au Total: " + compteur);
            }
    Qu'est ce que j'aurais oublié dans mon code ? je sèche un peu là

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    3 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 001
    Par défaut
    Ce n'et pas très clair.
    Mais en tout cas tu as mis un timeout sur la commande et non sur la connexion.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    oConnection.ConnectionTimeout = 5;
    oConnection.Open();

  3. #3
    Membre confirmé
    Homme Profil pro
    Webmaster
    Inscrit en
    Octobre 2014
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Antilles Néerlandaises

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Octobre 2014
    Messages : 73
    Par défaut
    Ba en fait j'ai mis un timeout sur le sql command et un timeout dans la connection string.
    Et pour être sur que dans la connection string ce soit pris en compte j'ai affiché sa valeur dans la console pendant le traitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Console.WriteLine("Apres ouverture connexion : Time-Out Réglé sur " + oConnection.ConnectionTimeout);
    La valeur est bien affiché correctement pendant le traitement, mais peu importe ce que je mets j'ai toujours 30 secondes d'attentes au début quand je tape un mauvais nom de serveur.
    Si j'essaie de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    oConnection.ConnectionTimeout = 5
    Visual studio me dit que la propriété est en lecture seule et me surligne la ligne en rouge.

  4. #4
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    En fait il manque un genre de mecanisme de "ping" a l'objet SqlConnection. Le probleme est decrit ici, et ils donnent une solution basee sur une methode d'extension : Controlling SqlConnection Timeouts.

    Pour resumer en Francais, le pipeline de connexion est comme suit :
    TCP Connection to SQL Server --> SqlConnection.Open() --> SqlCommand.Execute()
    Les timeouts des objets SqlConnection et SqlCommand couvrent les 2 derniers points mais pas le premier.

    L'idee consiste a lancer une requete TCP vers le serveur SQL en premier. Si on est OK, on ouvre la connexion a SQL Server, sinon on lance une exception plus rapidement. Voici le code suggere dans le lien ci-dessus, avec les commentaires en Francais :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public static class SqlExtensions
    {
        public static void QuickOpen(this SqlConnection conn, int timeout)
        {
            // On utilise un Stopwatch pour plus de simplicite. On peut aussi faire une comparaison avec un DateTime.Now stocke
            Stopwatch sw = new Stopwatch();
            bool connectSuccess = false;
     
            // On essaie d'ouvrir la connexion. Si quelque chose ne marche pas, on met connectSuccess = false
            Thread t = new Thread(delegate()
            {
                try
                {
                    sw.Start();
                    conn.Open();
                    connectSuccess = true;
                }
                catch { }
            });
     
            // On marke le thread en tant que thread d'arriere plan pour qu'il soit nettoye automatiquement
            t.IsBackground = true;
            t.Start();
     
            // On essaie de joindre le thread jusqu'a ce qu'on arrive a se connecter, ou jusqu'a ce que la valeur du timeout soit depassee
            while (timeout > sw.ElapsedMilliseconds)
                if (t.Join(1))
                    break;
     
            // Si on n'arrive pas a se connecter, on leve une exception
            if (!connectSuccess)
                throw new Exception("Timed out while trying to connect.");
        }
    }
    Pour l'utiliser :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using Namespace.xxx.yyy; // On ajoute le namespace dans lequel se trouve la classe SqlExtensionsvar con = new SqlConnection();
    con.QuickOpen(5000); // On essaie d'ouvrir la connexion a SQL Server avec un timeout de 5 secondes


    Bien entendu il faut prevoir une logique de gestion des erreurs adaptee puisque QuickOpen() peut lever une exception.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  5. #5
    Membre confirmé
    Homme Profil pro
    Webmaster
    Inscrit en
    Octobre 2014
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Antilles Néerlandaises

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Octobre 2014
    Messages : 73
    Par défaut
    Hello DotNetMatt,

    ta solution marche au poil. Un grand merci car je n'aurais pas trouvé tout seul vu mon niveau en c#.

    j'ai donc crée une nouvelle classe contenant ton code et ensuite j'ai rajouté un using static dans la classe que j'utilise actuellement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using static WpfApp1.SqlExtensions;

    Merci encore d'avoir pris la peine de me répondre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. délai de requête trop long avec sql server
    Par tiferg dans le forum Projets ADP
    Réponses: 0
    Dernier message: 24/03/2010, 08h43
  2. Réponses: 19
    Dernier message: 01/02/2008, 11h54
  3. [SQL Server 2000] requête avec le nom de la table dynamique
    Par insane_80 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 07/12/2006, 17h57
  4. Connexion à SQL Server avec ASP
    Par ayobo dans le forum ASP
    Réponses: 3
    Dernier message: 25/05/2004, 17h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo