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.