web-dev-qa-db-fra.com

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

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

Maintenant, je viens d'essayer le Exemple 1 ( ici est le lien vers MSDN), et j'ai rencontré un problème: pourquoi la fenêtre de la console se ferme-t-elle immédiatement après l'affichage de ma sortie ?

using System;

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

le problème ici est que leur programme Hello World se présente alors il se fermerait immédiatement.
pourquoi donc?

Puisqu'il est terminé. Lorsque l'exécution des applications de la console est terminée et qu'elles renvoient depuis leur méthode main, la fenêtre de la console associée se ferme automatiquement. C'est le comportement attendu.

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

La méthode Console.ReadLine est un moyen de le faire. Si vous ajoutez cette ligne à la fin de votre code (juste avant l'instruction return), 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+F5 depuis 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 utiliser lors de l'écriture d'une application.

Le meilleur compromis est probablement d'appeler la méthode Console.ReadLine 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 est levée. Pour ce faire, vous pouvez placer la Console.ReadLine(); dans un bloc finally:

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

À 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 laissera la fenêtre de la console ouverte jusqu'à ce que vous appuyiez sur une touche.

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

60
Bhavik Patel

Cela se comporte de la même manière pour CtrlF5 ou F5. Placez immédiatement avant la fin de la méthode Main.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

Je suppose que la raison pour laquelle vous ne voulez pas fermer 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 un point d'arrêt sur le "}" de fermeture de la fonction principale . Si vous n'avez pas besoin de déboguer, Ctrl-F5 est la meilleure option.

8
Rob L

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 la fermeture du programme.

6
Robert Rouhani

Alternativement, vous pouvez retarder la fermeture en utilisant le code suivant:

System.Threading.Thread.Sleep(1000);

Notez que la Sleep utilise des millisecondes.

4
gotqn

Une autre méthode consiste à utiliser Debugger.Break() avant de revenir de la méthode Main

4
dimaaan

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

Console.ReadLine();

ou

Console.Read();
3
Ari

Ajoutez la méthode Read pour afficher le résultat. 

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

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

    Console.Read(); 
    return 0; 

vérifier ceci Console.Lire

3
Ravi Gadag

Si vous voulez garder votre application ouverte, vous devez faire quelque chose pour que son processus reste actif. L'exemple ci-dessous est l'exemple le plus simple, à mettre à la fin de votre programme:

while (true) ;

Cependant, cela surchargera le processeur, ce qui le contraindra à itérer indéfiniment.

A ce stade, vous pouvez choisir d'utiliser la classe System.Windows.Forms.Application (mais il faut ajouter la référence System.Windows.Forms):

Application.Run();

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

Afin d'éviter d'ajouter la référence System.Windows.Forms, vous pouvez utiliser une astuce simple, appelée spin waiting, qui importe System.Threading:

SpinWait.SpinUntil(() => false);

Cela fonctionne également parfaitement et consiste principalement en un itérateur while avec une condition annulée qui est renvoyée par la méthode lambda ci-dessus. Pourquoi ne pas surcharger le processeur? Vous pouvez regarder le code source ici ; de toute façon, les instructions restent en cours d’attente. 

Vous pouvez également opter pour la création d'un boucleur de message, qui visualise les messages en attente et les traite avant de les transmettre à l'itération suivante:

[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 faire une boucle en toute sécurité en faisant quelque chose comme ceci:

while (true)
    ProcessMessageOnce();

Mieux encore, vous pouvez mélanger les deux dernières solutions en remplaçant l'itérateur while par une invocation SpinWait.SpinUntil:

SpinWait.SpinUntil(ProcessMessageOnce);
2
Davide Cannizzo

Je suis un peu en retard pour la fête, mais: dans les projets Visual Studio 2019 pour .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 votre fenêtre de console se ferme automatiquement, vérifiez si le paramètre mentionné n’est pas défini.

Il en va de même pour les nouveaux projets de console de style .NET Framework:

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

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

</Project>

L'ancien projet .NET Framework de style ferme toujours 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/

1
Vlad

Le programme se ferme dès que son exécution est terminée. Dans ce cas, lorsque vous return 0;. C'est la fonctionnalité attendue. Si vous voulez voir la sortie, exécutez-la manuellement dans un terminal ou définissez un délai d'attente à la fin du programme pour qu'il reste ouvert quelques secondes (à l'aide de la bibliothèque de threading).

0
zellio

Voici un moyen de le faire sans impliquer Console:

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