Perché la finestra della console si chiude immediatamente una volta visualizzato il mio output?


158

Sto studiando C # seguendo le guide in MSDN .

Ora, ho appena provato l' esempio 1 ( ecco il link a MSDN ) e ho riscontrato un problema: perché la finestra della console si chiude immediatamente una volta visualizzato il mio output?

using System;

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

Puoi provare ad aprire con la console. Trascina e rilascia sulla console e premi "Invio". Presumo sia un file EXE.
Sajidur Rahman,

Se si sta cercando di eseguire il debug di un programma a riga di comando che viene avviato da un processo esterno, vedere questa domanda: stackoverflow.com/a/23334014/3195477
UuDdLrLrSs

Risposte:


266

il problema qui è che il loro programma Hello World si sta manifestando e si chiuderà immediatamente.
perché?

Perché è finito. Quando le applicazioni della console hanno completato l'esecuzione e ritornano dal loro mainmetodo, la finestra della console associata si chiude automaticamente. Questo è un comportamento previsto.

Se si desidera mantenerlo aperto a scopo di debug, è necessario indicare al computer di attendere la pressione di un tasto prima di terminare l'app e chiudere la finestra.

Il Console.ReadLinemetodo è un modo per farlo. L'aggiunta di questa riga alla fine del codice (appena prima returndell'istruzione) farà attendere all'applicazione di premere un tasto prima di uscire.

In alternativa, è possibile avviare l'applicazione senza il debugger collegato premendo Ctrl+ F5dall'interno dell'ambiente di Visual Studio, ma questo ha l'ovvio svantaggio di impedirti di utilizzare le funzionalità di debug, che probabilmente desideri essere a tua disposizione durante la scrittura di un'applicazione.

Il miglior compromesso è probabilmente quello di chiamare il Console.ReadLinemetodo solo quando si esegue il debug dell'applicazione avvolgendolo in una direttiva preprocessore. Qualcosa di simile a:

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

È inoltre possibile che la finestra rimanga aperta se viene generata un'eccezione non rilevata. Per fare ciò puoi inserire Console.ReadLine();un finallyblocco:

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

18
In alternativa, è possibile utilizzare Console.ReadKey ();
PlantationGator,

55
Personalmente, preferisco if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();.
Sameer Singh,

5
Perché l'esecuzione senza il debug modifica questo comportamento? Penseresti che dovrebbe essere un'esperienza più accurata, non meno.
Kyle Delaney,

@SameerSingh Un'altra riga di codice non necessario compilata nel tuo binario. In realtà preferisco questo approccio al preprocessore.
Gioele,

@Joel Perché, in generale, dovremmo preoccuparcene in questi giorni?
Alex

66

Invece di usare

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

puoi eseguire il tuo programma usando Ctrl+ F5(se sei in Visual Studio). Quindi Visual Studio manterrà aperta la finestra della console, fino a quando non si preme un tasto.

Nota: non è possibile eseguire il debug del codice in questo approccio.


Ciao utente. Sono un nuovo utente di VS e C # anche in generale. Cosa fa Ctrl + F5diversamente che semplicemente Startfanno diversamente?
theGreenCabbage il

sfortunatamente, a volte smette di funzionare come previsto.
MaikoID

2
La causa del problema è che Windows chiude automaticamente la finestra del terminale quando il programma si arresta. Altri sistemi manterranno automaticamente la finestra aperta. Questo è il modo migliore per eseguire il programma. Non usare ReadKey, Read o ReadLine per queste cose poiché questo impedisce al tuo programma di essere utilizzato in combinazione con altre applicazioni console e tubazioni.
tempo reale

14

Suppongo che il motivo per cui non si desidera che si chiuda in modalità Debug, è perché si desidera esaminare i valori delle variabili, ecc. Quindi è probabilmente meglio inserire un punto di interruzione sul "}" di chiusura della funzione principale . Se non è necessario eseguire il debug, Ctrl-F5 è l'opzione migliore.


Sorpreso, nessuna delle altre risposte ha suggerito questo. È raro che una risposta con una nuova opzione venga aggiunta così tardi dopo la creazione della domanda.
Scott Chamberlain,

13

Questo si comporta allo stesso modo per CtrlF5o F5. Posizionare immediatamente prima della fine del Mainmetodo.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

7
Solo per notare, l'ultima riga dovrebbe essere Console.ReadKey()per qualsiasi tasto, in Console.ReadLine()attesa che venga premuto Invio
Chris

6

Il programma si chiude immediatamente perché non c'è nulla che gli impedisca di chiudere. Inserire un punto di interruzione in return 0;o aggiungere Console.Read();prima return 0;per impedire la chiusura del programma.


5

Sono un po 'in ritardo alla festa, ma: nei progetti Visual Studio 2019 per .NET Core la console non si chiude automaticamente per impostazione predefinita. È possibile configurare il comportamento tramite il menu Strumenti → Opzioni → Debug → Generale → Chiudi automaticamente la console quando il debug si interrompe. Se si chiude automaticamente la finestra della console, verificare che l'impostazione menzionata non sia impostata.

Lo stesso vale per i progetti della nuova console di .NET Framework:

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

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

</Project>

Alla fine il vecchio progetto .NET Framework chiude incondizionatamente la console (a partire da Visual Studio 16.0.1).

Riferimento: https://devblogs.microsoft.com/dotnet/net-core-tooling-update-for-visual-studio-2019-preview-2/


Questa opzione è disponibile per me in VS2017 15.9.4 ma non funziona per la mia applicazione console .net core 2.1 ...
user1073075

@ user1073075: questo è strano. La funzione funziona per altri target?
Vlad

No. Ho provato con un'app console .NET framework e ancora non ha funzionato. (Ho installato VS2019 su una macchina diversa e lì funziona. Forse è un bug in VS17 15.9.4)
user1073075

Con il 2019 funziona ora anche per i progetti WPF: pastebin.com/FpAeV0cW . Ma devi installare .NET Core 3.
Vlad

5

Se vuoi mantenere aperta la tua applicazione, devi fare qualcosa per mantenere vivo il suo processo. L'esempio seguente è il più semplice, da mettere alla fine del programma:

while (true) ;

Tuttavia, causerà un sovraccarico della CPU, poiché è quindi costretto a scorrere all'infinito.

A questo punto, puoi scegliere di utilizzare la System.Windows.Forms.Applicationclasse (ma è necessario aggiungere un System.Windows.Formsriferimento):

Application.Run();

Questo non perde la CPU e funziona correttamente.

Per evitare di aggiungere System.Windows.Formsriferimenti, è possibile utilizzare un semplice trucco, il cosiddetto spin in attesa , importando System.Threading:

SpinWait.SpinUntil(() => false);

Anche questo funziona perfettamente e sostanzialmente consiste in un whileciclo con una condizione negata che viene restituita dal metodo lambda sopra. Perché questa CPU non sovraccarica? Puoi guardare il codice sorgente qui ; comunque, in pratica attende qualche ciclo della CPU prima di ripetere.

È inoltre possibile creare un looper di messaggi, che visualizza i messaggi in sospeso dal sistema e li elabora prima di passare alla successiva iterazione, come segue:

[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;
}

Quindi, puoi eseguire il loop in sicurezza facendo una cosa del genere:

while (true)
    ProcessMessageOnce();

Non so se questo perde CPU o no ma; funziona correttamente. Grazie.
Mumin Ka

4

In alternativa, puoi ritardare la chiusura utilizzando il seguente codice:

System.Threading.Thread.Sleep(1000);

Nota che Sleepsta usando millisecondi.


4

Un altro modo è quello di utilizzare Debugger.Break()prima di tornare dal metodo principale


Anche se questa opzione si focalizza nuovamente sulla finestra del debugger e potenzialmente nasconde il contenuto della finestra della console.
Stephen Turner,

3

Il codice è terminato, per continuare devi aggiungere questo:

Console.ReadLine();

o

Console.Read();

3

Usa Console.Read (); per impedire la chiusura del programma, ma assicurati di aggiungere il Console.Read();codice prima dell'istruzione return, altrimenti sarà un codice irraggiungibile.

    Console.Read(); 
    return 0; 

controlla questa Console. Leggi


3

Aggiungi Il Readmetodo per mostrare l'output.

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

1

Ecco un modo per farlo senza coinvolgere Console:

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

0

Il programma si chiude non appena la sua esecuzione è completa. In questo caso quando tu return 0;. Questa è una funzionalità prevista. Se vuoi vedere l'output, eseguilo manualmente in un terminale o imposta un'attesa alla fine del programma in modo che rimanga aperto per alcuni secondi (usando la libreria di threading).


0

questa è la risposta asincrona all'app console in C #?

qualsiasi cosa ovunque nell'app della console non usi mai awaitma invece usi theAsyncMethod().GetAwaiter().GetResult();,

esempio

var result = await HttpClientInstance.SendAsync(message);

diventa

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


-3

se il programma richiede di premere Invio per continuare come se fosse necessario immettere un valore e continuare, quindi aggiungere un nuovo doppio o int e digitare write prima di eseguire nuovamente (0); scanf_s ("% lf", & la variabile);


1
Questa è una domanda C # .
Wai Ha Lee,

-3

Aggiungo sempre la seguente dichiarazione a un'applicazione console (se lo desideri, crea uno snippet di codice per questo)

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

Ciò aiuta quando si desidera sperimentare concetti diversi tramite l'applicazione console.

Ctr + F5 farà rimanere la console ma non è possibile eseguire il debug! Tutte le applicazioni console che ho scritto nel mondo reale sono sempre non interattive e attivate da uno Scheduler come TWS o CA Work Station e non richiedono qualcosa di simile.


-3

Per semplificare ciò che gli altri dicono: Usa Console.ReadKey();.

Questo rende il programma in attesa che l'utente prema un tasto normale sulla tastiera

Fonte: lo uso nei miei programmi per applicazioni console.


-3

Puoi risolverlo in modo molto semplice semplicemente invocando l'input. Tuttavia, se si preme, Enterla console scompare di nuovo. Basta usare questo Console.ReadLine();oConsole.Read();


-4

Aggiungere quanto segue prima del ritorno 0:

system("PAUSE");  

Questo stampa una linea per premere un tasto per chiudere la finestra. Manterrà la finestra aperta fino a quando non si preme il tasto Invio. Ho i miei studenti aggiungerlo a tutti i loro programmi.


1
questo è in c ++
Gonçalo Garrido,

-13

Secondo la mia preoccupazione, se vogliamo stabilizzare l'USCITA DELL'APPLICAZIONE DELLA CONSOLLE, fino alla chiusura dell'output visualizzi USE, l'etichetta: dopo il MainMethod e vai all'etichetta; prima della fine del programma

Nel programma

per esempio:

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

    // Snippet of code

    goto label;
}

2
Ciò farà semplicemente continuare a stampare il programma di manifesti "Ciao, mondo!" molte volte
David Post

1
Gesù Cristo, non sapevo che gotoun'affermazione fosse neppure consentita in C #.
Ch3shire,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.