Pourquoi la fenêtre de la console se ferme-t-elle immédiatement une fois ma sortie affichée?


158

J'étudie C # en suivant les guides de MSDN .

Maintenant, je viens d'essayer l' exemple 1 ( voici le lien vers MSDN ), et j'ai rencontré un problème: pourquoi la fenêtre de la console se ferme-t-elle immédiatement une fois ma sortie affichée?

using System;

public class Hello1
{
    public static int Main()
    {
        Console.WriteLine("Hello, World!");
        return 0;
    }
}

Vous pouvez essayer d'ouvrir avec la console. Faites-le glisser et déposez-le sur la console et appuyez sur "Entrée". Je suppose que c'est un fichier EXE.
Sajidur Rahman

Si vous essayez de DEBUGER un programme de ligne de commande qui est démarré par un processus externe, consultez cette question: stackoverflow.com/a/23334014/3195477
UuDdLrLrSs

Réponses:


267

le problème ici est que leur programme Hello World apparaît, puis il se fermera immédiatement.
pourquoi donc?

Parce que c'est fini. Lorsque les applications de la console ont terminé l'exécution et retournent de leur mainméthode, la fenêtre de la console associée se ferme automatiquement. Il s'agit d'un comportement attendu.

Si vous souhaitez le garder ouvert à des fins de débogage, vous devrez demander à l'ordinateur d'attendre une pression sur une touche avant de mettre fin à l'application et de fermer la fenêtre.

La Console.ReadLineméthode est une façon de faire cela. Si vous ajoutez cette ligne à la fin de votre code (juste avant l' returninstruction), l'application attendra que vous appuyiez sur une touche avant de quitter.

Vous pouvez également démarrer l'application sans le débogueur attaché en appuyant sur Ctrl+ à F5partir de l'environnement Visual Studio, mais cela présente l'inconvénient évident de vous empêcher d'utiliser les fonctionnalités de débogage, que vous souhaitez probablement à votre disposition lors de l'écriture d'une application.

Le meilleur compromis est probablement d'appeler la Console.ReadLineméthode uniquement lors du débogage de l'application en l'enveloppant dans une directive de préprocesseur. Quelque chose comme:

#if DEBUG
    Console.WriteLine("Press enter to close...");
    Console.ReadLine();
#endif

Vous pouvez également souhaiter que la fenêtre reste ouverte si une exception non interceptée a été levée. Pour ce faire, vous pouvez mettre le Console.ReadLine();dans un finallybloc:

#if DEBUG
    try
    {
        //...
    }
    finally
    {
        Console.WriteLine("Press enter to close...");
        Console.ReadLine();
    }
#endif

18
Vous pouvez également utiliser Console.ReadKey ();
PlantationGator

55
Personnellement, je préfère if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();.
Sameer Singh

5
Pourquoi l'exécution sans débogage change-t-elle ce comportement? Vous penseriez que ce devrait être une expérience plus précise, pas moins.
Kyle Delaney

@SameerSingh Une ligne de plus de code inutile en cours de compilation dans votre binaire. Je préfère en fait cette approche préprocesseur.
Joel

@Joel Pourquoi devrions-nous, en général, nous soucier de cela ces jours-ci?
Alex le

66

À la place d'utiliser

Console.Readline()
Console.Read()
Console.ReadKey()

vous pouvez exécuter votre programme en utilisant Ctrl+ F5(si vous êtes dans Visual Studio). Ensuite, Visual Studio gardera la fenêtre de la console ouverte jusqu'à ce que vous appuyiez sur une touche.

Remarque: vous ne pouvez pas déboguer votre code dans cette approche.


Salut utilisateur. Je suis également un nouvel utilisateur de VS et de C # en général. Qu'est-ce qui Ctrl + F5fait différemment qui fait tout simplement Startdifféremment?
theGreenCabbage

malheureusement, il s'arrête parfois de fonctionner comme prévu.
MaikoID

2
La cause du problème est que Windows ferme automatiquement la fenêtre du terminal lorsque le programme s'arrête. D'autres systèmes garderont la fenêtre ouverte automatiquement. C'est la meilleure façon d'exécuter le programme. N'utilisez pas ReadKey, Read ou ReadLine pour ce genre de choses car cela empêche votre programme d'être utilisé en combinaison avec d'autres applications de console et de canalisation.
temps réel du

14

Je suppose que la raison pour laquelle vous ne voulez pas qu'il se ferme en mode Débogage, c'est parce que vous voulez regarder les valeurs des variables etc. Il est donc probablement préférable d'insérer simplement un point d'arrêt sur la fermeture "}" de la fonction principale . Si vous n'avez pas besoin de déboguer, alors Ctrl-F5 est la meilleure option.


Surpris, aucune des autres réponses n'a suggéré cela. Il est rare qu'une réponse avec une nouvelle option soit ajoutée si tard après la création de la question.
Scott Chamberlain

13

Cela se comporte de la même manière pour CtrlF5ou F5. Placer immédiatement avant la fin de la Mainméthode.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

  if (Debugger.IsAttached) {
    Console.WriteLine("Press any key to continue . . .");
    Console.ReadLine();
  }
}

7
Juste à noter, la dernière ligne devrait être Console.ReadKey()pour n'importe quelle touche, Console.ReadLine()attend que vous appuyiez sur Entrée
Chris

6

Le programme se ferme immédiatement car rien ne l'empêche de se fermer. Insérez un point d'arrêt à return 0;ou ajoutez Console.Read();avant return 0;pour empêcher le programme de se fermer.


5

Je suis un peu en retard à la fête, mais: dans Visual Studio 2019 pour les projets .NET Core, la console ne se ferme pas automatiquement par défaut. Vous pouvez configurer le comportement via le menu Outils → Options → Débogage → Général → Fermer automatiquement la console lorsque le débogage s'arrête. Si vous obtenez la fermeture automatique de la fenêtre de votre console, vérifiez si le paramètre mentionné n'est pas défini.

La même chose s'applique aux projets de console de nouveau style .NET Framework:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472</TargetFramework>
  </PropertyGroup>

</Project>

L'ancien projet .NET Framework ferme toujours inconditionnellement la console à la fin (à partir de Visual Studio 16.0.1).

Référence: https://devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2019-preview-2/


Cette option est disponible pour moi dans VS2017 15.9.4 mais elle ne fonctionne pas pour mon application console .net core 2.1 ...
user1073075

@ user1073075: c'est étrange. La fonctionnalité fonctionne-t-elle pour d'autres cibles?
Vlad

Non. Essayé avec une application de console .NET Framework et ne fonctionne toujours pas. (J'ai installé VS2019 sur une machine différente et là ça marche. Peut-être que c'est un bogue dans VS17 15.9.4)
user1073075

Avec 2019, cela fonctionne maintenant même pour les projets WPF: pastebin.com/FpAeV0cW . Mais vous devez installer .NET Core 3.
Vlad

5

Si vous souhaitez garder votre application ouverte, vous devez faire quelque chose pour maintenir son processus en vie. L'exemple ci-dessous est le plus simple, à mettre à la fin de votre programme:

while (true) ;

Cependant, cela entraînera une surcharge du processeur, car il est donc obligé d'itérer à l'infini.

À ce stade, vous pouvez choisir d'utiliser la System.Windows.Forms.Applicationclasse (mais cela vous oblige à ajouter une System.Windows.Formsréférence):

Application.Run();

Cela ne fuit pas le processeur et fonctionne avec succès.

Afin d'éviter d'ajouter une System.Windows.Formsréférence, vous pouvez utiliser une astuce simple, la soi-disant attente de rotation , en important System.Threading:

SpinWait.SpinUntil(() => false);

Cela fonctionne également parfaitement et consiste essentiellement en une whileboucle avec une condition négative renvoyée par la méthode lambda ci-dessus. Pourquoi ce processeur ne surcharge-t-il pas? Vous pouvez consulter le code source ici ; Quoi qu'il en soit, il attend essentiellement un cycle du processeur avant de recommencer.

Vous pouvez également créer un boucleur de messages, qui examine les messages en attente du système et traite chacun d'eux avant de passer à l'itération suivante, comme suit:

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "PeekMessage")]
public static extern int PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "GetMessage")]
public static extern int GetMessage(out NativeMessage lpMsg, IntPtr hWnd, int wMsgFilterMin, int wMsgFilterMax);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "TranslateMessage")]
public static extern int TranslateMessage(ref NativeMessage lpMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode, DllImport("user32.dll", EntryPoint = "DispatchMessage")]
public static extern int DispatchMessage(ref NativeMessage lpMsg);

[DebuggerHidden, DebuggerStepperBoundary, DebuggerNonUserCode]
public static bool ProcessMessageOnce()
{
    NativeMessage message = new NativeMessage();

    if (!IsMessagePending(out message))
        return true;

    if (GetMessage(out message, IntPtr.Zero, 0, 0) == -1)
        return true;

    Message frameworkMessage = new Message()
    {
        HWnd = message.handle,
        LParam = message.lParam,
        WParam = message.wParam,
        Msg = (int)message.msg
    };

    if (Application.FilterMessage(ref frameworkMessage))
        return true;

    TranslateMessage(ref message);
    DispatchMessage(ref message);

    return false;
}

Ensuite, vous pouvez boucler en toute sécurité en faisant quelque chose comme ceci:

while (true)
    ProcessMessageOnce();

Je ne sais pas si cela fuit le processeur ou non mais; fonctionne avec succès. Je vous remercie.
Mumin Ka le

4

Vous pouvez également retarder la fermeture à l'aide du code suivant:

System.Threading.Thread.Sleep(1000);

Notez que le Sleeputilise des millisecondes.


4

Une autre façon est d'utiliser Debugger.Break()avant de revenir de la méthode Main


Bien que ce commutateur se concentre sur la fenêtre du débogueur et masque potentiellement le contenu de la fenêtre de la console.
Stephen Turner

3

Le code est terminé, pour continuer, vous devez ajouter ceci:

Console.ReadLine();

ou

Console.Read();

3

Utilisez Console.Read (); pour empêcher le programme de se fermer, mais assurez-vous d'ajouter le Console.Read();code avant l'instruction return, sinon ce sera un code inaccessible.

    Console.Read(); 
    return 0; 

vérifiez cette console.


3

Add La Readméthode pour afficher la sortie.

Console.WriteLine("Hello, World!");
Console.Read();
return 0;

1

Voici une façon de le faire sans impliquer Console:

var endlessTask = new TaskCompletionSource<bool>().Task;
endlessTask.Wait();

0

Le programme se ferme dès que son exécution est terminée. Dans ce cas, lorsque vous return 0;. C'est une fonctionnalité attendue. Si vous voulez voir la sortie, exécutez-la manuellement dans un terminal ou définissez une attente à la fin du programme afin qu'elle reste ouverte pendant quelques secondes (en utilisant la bibliothèque de threads).


0

c'est la réponse asynchrone à l'application console en C #?

n'importe où dans l'application console, n'utilisez jamais awaitmais utilisez plutôt theAsyncMethod().GetAwaiter().GetResult();,

exemple

var result = await HttpClientInstance.SendAsync(message);

devient

var result = HttpClientInstance.SendAsync(message).GetAwaiter().GetResult();


-3

si votre programme vous oblige à appuyer sur Entrée pour continuer comme vous devez entrer une valeur et continuer, ajoutez un nouveau double ou int et tapez write avant retunr (0); scanf_s ("% lf", & la variable);


1
C'est une question C # .
Wai Ha Lee

-3

J'ajoute toujours l'instruction suivante à une application console (créez un extrait de code pour cela si vous le souhaitez)

Console.WriteLine("Press any key to quit!");
Console.ReadKey();

Cela aide lorsque vous souhaitez expérimenter différents concepts via une application console.

Ctr + F5 fera rester la console mais vous ne pouvez pas déboguer! Toutes les applications console que j'ai écrites dans realworld sont toujours non interactives et déclenchées par un planificateur tel que TWS ou CA Work station et ne nécessitent pas quelque chose comme ça.


-3

Pour simplifier ce que les autres disent: utilisez Console.ReadKey();.

Cela permet au programme d'attendre que l'utilisateur appuie sur une touche normale du clavier

Source: je l'utilise dans mes programmes pour les applications console.


-3

Vous pouvez le résoudre de manière très simple en invoquant simplement l'entrée. Cependant, si vous appuyez sur, Enterla console disparaîtra à nouveau. Utilisez simplement ceci Console.ReadLine();ouConsole.Read();


-4

Ajoutez ce qui suit avant le retour 0:

system("PAUSE");  

Cela imprime une ligne pour frapper une touche pour fermer la fenêtre. Il gardera la fenêtre ouverte jusqu'à ce que vous appuyiez sur la touche Entrée. Je demande à mes étudiants de l'ajouter à tous leurs programmes.


1
thats is in c ++
Gonçalo Garrido

-13

Selon ma préoccupation, si nous voulons stabiliser la SORTIE DE L'APPLICATION CONSOLE, jusqu'à la fermeture de la sortie affiche USE, le label: après la MainMethod, et goto label; avant la fin du programme

Dans le programme.

par exemple:

static void Main(string[] args)
{
    label:

    // Snippet of code

    goto label;
}

2
Le programme d'affiches continuera à imprimer "Hello, World!" plusieurs fois
DavidPostill

1
Jésus-Christ, ne savait même pas que la gotodéclaration était autorisée en C #.
Ch3shire
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.