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 :

[Console] Réponse utilisateur ou exécution dans quelques secondes


Sujet :

C#

  1. #1
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut [Console] Réponse utilisateur ou exécution dans quelques secondes
    Salut,

    Situation :
    Je suis en train de créer une application console qui demande à l'utilisateur de confirmer un paramètre. Si l'utilisateur n'a pas répondu dans 5 secondes alors on exécute le code avec la valeur spécifiée.

    Problème :
    Avec le code si dessous je ne sors jamais de ma boucle "while(true)" pour lire la réponse de l'utilisateur.

    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
    39
    40
    41
    42
    43
            static void Main()
            {
                bool reponse = true;
                Console.WriteLine("Oui ou non (o/n) ?");
                Delayed(5000, () => DoAction(reponse));
                while (true)
                {
                    var consoleKey = Console.ReadKey().Key;
     
                    if (consoleKey.Equals(ConsoleKey.O))
                    {
                        reponse = true;
                        break;
                    }
                    else if (consoleKey.Equals(ConsoleKey.N))
                    {
                        reponse = false;
                        break;
                    }
                }
     
                Console.WriteLine();
                DoAction(reponse);
                Console.ReadLine();
            }
     
            public static void DoAction(bool reponse)
            {
                if (reponse) Console.WriteLine("Oui");
                else Console.WriteLine("Non");
            }
     
            private static void Delayed(int delay, Action action)
            {
                Timer timer = new Timer();
                timer.Interval = delay;
                timer.Elapsed += (s, e) =>
                {
                    action();
                    timer.Stop();
                };
                timer.Start();
            }

    Merci d'avance.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    T'as quelques solutions simples à mettre en place ici:

    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
     
            static void Main(string[] args)
            {
                while (true)
                {
                    Console.WriteLine("Oui ou non (o/n) ?");
                    ConsoleKey resp = ReadKeyYesDefault();
                    if (resp == ConsoleKey.O)
                        Console.WriteLine(Environment.NewLine + "Vous avez choisi de mourir");
                    else
                        Console.WriteLine(Environment.NewLine + "Alive");
                }
            }
     
            static ConsoleKey ReadKeyYesDefault()
            {
                var task = Task.Run(() => Console.ReadKey());
                bool read = task.Wait(3000);
                if (read) return task.Result.Key;
                return ConsoleKey.O;
            }

  3. #3
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Citation Envoyé par alavoler Voir le message
    T'as quelques solutions simples à mettre en place ici:
    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
     
            static void Main(string[] args)
            {
                Console.WriteLine("Oui ou non (o/n) ?");
                ConsoleKey resp = ReadKeyYesDefault();
                if (resp == ConsoleKey.O)
                    Console.WriteLine("\nVous avez choisi de mourir");
                Console.ReadKey();
            }
     
            static ConsoleKey ReadKeyYesDefault()
            {
                var task = Task.Run(() => Console.ReadKey());
                bool read = task.Wait(5000);
                if (read) return task.Result.Key;
                return ConsoleKey.O;
            }
    Merci cela à l'air d'être parfait. A mettre en situation maintenant.

    Edit : (C'est bon)

    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
            static void Main()
            {
                Console.WriteLine("Oui ou non (o/n) ?");
                var response = ReadKeyOrDefault();
                Console.WriteLine();
                if (response)
                    Console.WriteLine("Oui");
                else
                    Console.WriteLine("Non");
                Console.ReadLine();
            }
     
            static bool ReadKeyOrDefault()
            {
                var task = Task.Run(() => 
                {
                    while (true)
                    {
                        var consoleKey = Console.ReadKey().Key;
                        if (consoleKey.Equals(ConsoleKey.O))
                            return true;
                        else if (consoleKey.Equals(ConsoleKey.N))
                            return false;
                    }
                });
                bool read = task.Wait(5000);
                if (read)
                    return task.Result;
                else
                    return true;
            }

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    katkiller
    Je t'ai laissé un subtile bug quand même,
    lorsque le ReadKey n'est pas consommé... au prochain ReadKey... il doit l’Être
    En gros si t'attend 5 ReadKey (avec la réponse automatique) et bien il faudra écrire 5 caractères pour déclencher l'action...

    Je sais pas si y a un flush / clear du buffer... j'ai pas trouvé d'astuce, même un write('O') ne suffit pas

  5. #5
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Citation Envoyé par alavoler Voir le message
    katkiller
    Je t'ai laissé un subtile bug quand même,
    lorsque le ReadKey n'est pas consommé... au prochain ReadKey... il doit l’Être
    En gros si t'attend 5 ReadKey (avec la réponse automatique) et bien il faudra écrire 5 caractères pour déclencher l'action...

    Je sais pas si y a un flush / clear du buffer... j'ai pas trouvé d'astuce, même un write('O') ne suffit pas
    Effectivement, bonne remarque
    Je viens de me heurter à ce problème.

    Si quelqu'un a une solution, je suis preneur !

    Pour bien réexpliquer le problème :
    Si j'appelle une deuxième fois ma méthode pour demander à l'utilisateur si je doit continuer et que sur le premier choix l'utilisateur n'a rien sélectionné, il est obligé d'écrire deux fois la lettre pour valider son choix...

    Voici un exemple ou j'appel deux fois la méthode "ReadKeyOrDefault()" et ou je suis obligé d'écrire deux lettre pour que mon deuxième choix soit prit en compte :
    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
    static void Main()
            {
                Console.WriteLine("Oui ou non (o/n) ?");
                var response = ReadKeyOrDefault();
                Console.WriteLine();
                if (response)
                    Console.WriteLine("Oui 1");
                else
                    Console.WriteLine("Non 1");
     
                var response2 = ReadKeyOrDefault();
                Console.WriteLine();
                if (response2)
                    Console.WriteLine("Oui 2");
                else
                    Console.WriteLine("Non 2");
                Console.ReadLine();
            }
     
            static bool ReadKeyOrDefault()
            {
                var task = Task.Run(() => 
                {
                    while (true)
                    {
                        var consoleKey = Console.ReadKey().Key;
                        if (consoleKey.Equals(ConsoleKey.O))
                            return true;
                        else if (consoleKey.Equals(ConsoleKey.N))
                            return false;
                    }
                });
                bool read = task.Wait(5000);
                if (read)
                    return task.Result;
                else
                    return true;
            }
    PS : en plus le projet sur lequel je bosse est en 3.5 j'ai du passer passer par la librairie : TaskParallelLibrary

  6. #6
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Citation Envoyé par alavoler Voir le message
    Je sais pas si y a un flush / clear du buffer... j'ai pas trouvé d'astuce, même un write('O') ne suffit pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while (Console.KeyAvailable)
        Console.ReadKey (false);
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Citation Envoyé par Sehnsucht Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while (Console.KeyAvailable)
        Console.ReadKey (false);
    Je n'arrive pas a faire fonctionner ta proposition... Peut-être que c'est moi qu'il ne voit pas comment l'utiliser !

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    Citation Envoyé par katkiller Voir le message
    Je n'arrive pas a faire fonctionner ta proposition... Peut-être que c'est moi qu'il ne voit pas comment l'utiliser !
    pareil... je sèche la, c'est trop bas niveau pour que je puisse savoir (ralala l'excuse ^^)

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 1 002
    Points : 552
    Points
    552
    Par défaut
    J'ai pas trouvé mieux que de créer un Input réel
    J'ai utilisé une lib externe http://inputsimulator.codeplex.com/
    C'est pas miraculeux (car au changement de focus, ca Input ailleurs que dans la console... & co)
    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
                while (true)
                {
                    Console.WriteLine("Oui ou non (o/n) ?");
                    ConsoleKey resp = ReadKeyYesDefault();
                    if (resp == ConsoleKey.O)
                        Console.WriteLine(Environment.NewLine + "Vous avez choisi de mourir");
                    else
                        Console.WriteLine(Environment.NewLine + "Alive");
                }
            }
     
            static ConsoleKey ReadKeyYesDefault()
            {
     
                var task = Task.Run(() => Console.ReadKey());
                bool read = task.Wait(1000);
                if (read) return task.Result.Key;
                InputSimulator.SimulateKeyPress(VirtualKeyCode.VK_O);
                return task.Result.Key;
            }
    EDIT :::
    Le code de Mister TheMonz31 juste en bas est top

  10. #10
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    alors, on va faire beaucoup plus simple...

    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
     
    private static ConsoleKeyInfo WaitForKey(int ms)
            {
                int delay = 0;
                while (delay < ms)
                {
                    if (Console.KeyAvailable)
                    {
                        return Console.ReadKey();
                    }
                    Thread.Sleep(50);
                    delay += 50;
                }
                return new ConsoleKeyInfo((char)0, (ConsoleKey)0, false, false, false);
            }
    Comme ça, tu as une fonction qui te retourne un consoleKey à 0 si aucune touche, sinon, la touche appuyée..

    Car dans la version avec la Task.Run (), si tu regardes au debuggueur, tu te retrouves avec 2 Taches qui tourne quand tu as attendu les 5 premières secondes..
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  11. #11
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Merci Monz (et aux autres) c'est parfait et très simple !!!

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

Discussions similaires

  1. Exécuter une fonction après quelques secondes
    Par Akim13 dans le forum Langage
    Réponses: 13
    Dernier message: 12/03/2013, 17h56
  2. [MooTools] Exécution fonction après quelques secondes
    Par latour500 dans le forum Bibliothèques & Frameworks
    Réponses: 6
    Dernier message: 14/09/2012, 11h48
  3. Réponses: 4
    Dernier message: 16/12/2009, 12h26
  4. [SQL] Bloquer l'enregistrement dans une table pendant quelques secondes
    Par syl2042 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 04/09/2007, 10h19
  5. attente réponse utilisateur dans un formulaire
    Par Australia dans le forum Access
    Réponses: 11
    Dernier message: 25/01/2006, 15h49

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