it-swarm.com.de

Warum wird das Konsolenfenster sofort geschlossen, sobald meine Ausgabe angezeigt wird?

Ich studiere C #, indem ich die Anleitungen in MSDN befolge. 

Jetzt habe ich gerade das Example 1 ( hier ist der Link zu MSDN) ausprobiert, und ich bin auf ein Problem gestoßen: Warum wird das Konsolenfenster sofort geschlossen, sobald meine Ausgabe angezeigt wird? ?

using System;

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

das Problem hierbei ist, dass das Hello World-Programm angezeigt wird und dann sofort geschlossen wird.
Warum das?

Weil es fertig ist. Nachdem Konsolenanwendungen ausgeführt wurden und von ihrer Methode main zurückgekehrt sind, wird das zugehörige Konsolenfenster automatisch geschlossen. Dies ist das erwartete Verhalten.

Wenn Sie es für Debugging-Zwecke geöffnet lassen möchten, müssen Sie den Computer anweisen, auf einen Tastendruck zu warten, bevor Sie die App beenden und das Fenster schließen.

Die Console.ReadLine-Methode ist eine Möglichkeit, dies zu tun. Wenn Sie diese Zeile an das Ende Ihres Codes setzen (direkt vor der Anweisung return), wartet die Anwendung, bis Sie eine Taste drücken, bevor Sie sie beenden.

Alternativ können Sie die Anwendung auch starten, ohne dass der Debugger angehängt ist, indem Sie auf drücken Ctrl+F5 Dies hat jedoch den offensichtlichen Nachteil, dass Sie die Debugging-Funktionen nicht verwenden können, die Ihnen beim Schreiben einer Anwendung wahrscheinlich zur Verfügung stehen.

Der beste Kompromiss besteht wahrscheinlich darin, die Methode Console.ReadLine nur beim Debuggen der Anwendung aufzurufen, indem sie in eine Präprozessor-Direktive eingeschlossen wird. So etwas wie:

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

Möglicherweise soll das Fenster auch geöffnet bleiben, wenn eine nicht abgefangene Ausnahme ausgelöst wurde. Dazu können Sie die Console.ReadLine(); in einen finally -Block setzen:

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

Anstatt zu benutzen

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

sie können Ihr Programm mit ausführen Ctrl+F5 (wenn Sie in Visual Studio sind). Dann lässt Visual Studio das Konsolenfenster geöffnet, bis Sie eine Taste drücken.

Hinweis: Auf diese Weise können Sie Ihren Code nicht debuggen.

60
Bhavik Patel

Dies verhält sich auch für CtrlF5 oder F5. Platziere direkt vor dem Ende der Main Methode.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

Ich nehme an, der Grund dafür, dass Sie nicht im Debug-Modus schließen möchten, liegt darin, dass Sie die Werte von Variablen usw. betrachten möchten. Daher ist es am besten, einen Haltepunkt am schließenden "}" der Hauptfunktion einzufügen Wenn Sie nicht debuggen müssen, ist Strg-F5 die beste Option.

8
Rob L

Das Programm wird sofort geschlossen, da nichts das Schließen verhindert. Fügen Sie einen Haltepunkt bei return 0; ein oder fügen Sie Console.Read(); vor return 0; hinzu, um zu verhindern, dass das Programm geschlossen wird.

6
Robert Rouhani

Alternativ können Sie den Abschluss mit folgendem Code verzögern:

System.Threading.Thread.Sleep(1000);

Beachten Sie, dass Sleep Millisekunden verwendet.

4
gotqn

Eine andere Möglichkeit ist, Debugger.Break() zu verwenden, bevor Sie von der Main-Methode zurückkehren

4
dimaaan

Der Code ist fertig, um fortzufahren, müssen Sie Folgendes hinzufügen:

Console.ReadLine();

oder

Console.Read();
3
Ari

Fügen Sie die Read-Methode hinzu, um die Ausgabe anzuzeigen. 

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

Verwenden Sie Console.Read (); um zu verhindern, dass das Programm geschlossen wird, aber stellen Sie sicher, dass Sie den Code Console.Read(); vor der return-Anweisung hinzufügen, da es sonst zu einem nicht erreichbaren Code kommt. 

    Console.Read(); 
    return 0; 

Überprüfen Sie diese Console.Read

3
Ravi Gadag

Wenn Sie Ihre Anwendung geöffnet halten möchten, müssen Sie etwas tun, um den Prozess aufrecht zu erhalten. Das folgende ist das einfachste Beispiel, um es am Ende Ihres Programms zu platzieren:

while (true) ;

Dies führt jedoch zu einer Überlastung der CPU, da sie dazu gezwungen wird, unendlich oft zu iterieren.

An dieser Stelle können Sie die System.Windows.Forms.Application-Klasse verwenden (es ist jedoch erforderlich, System.Windows.Forms-Referenz hinzuzufügen):

Application.Run();

Dies verliert keine CPU und funktioniert erfolgreich. 

Um zu vermeiden, dass System.Windows.Forms referenziert wird, können Sie einen einfachen Trick verwenden, den sogenannten spin waiting, der System.Threading importiert:

SpinWait.SpinUntil(() => false);

Dies funktioniert auch einwandfrei und besteht hauptsächlich aus einem while-Iterator mit einem negierten Zustand, der von der obigen Lambda-Methode zurückgegeben wird. Warum überlastet diese CPU nicht? Sie können den Quellcode hier ; Trotzdem wartet er im Wesentlichen auf einen Zyklus des Prozessors, um die Anweisungen weiter auszuführen. 

Sie können sich auch für das Erstellen eines Nachrichtenschleifers entscheiden, der die anstehenden Nachrichten durchläuft und jede davon verarbeitet, bevor Sie zur nächsten Iteration übergehen:

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

Dann können Sie eine sichere Schleife machen, indem Sie Folgendes tun:

while (true)
    ProcessMessageOnce();

Noch besser, Sie könnten die beiden letztgenannten Lösungen kombinieren, indem Sie den Iterator while durch einen Aufruf von SpinWait.SpinUntil ersetzen:

SpinWait.SpinUntil(ProcessMessageOnce);
2
Davide Cannizzo

Ich bin ein bisschen spät dran an der Party, aber: In Visual Studio 2019 für .NET Core-Projekte wird die Konsole standardmäßig nicht automatisch geschlossen. Sie können das Verhalten über das Menü Extras → Optionen → Debuggen → Allgemein → Konsole automatisch schließen, wenn das Debuggen beendet wird. Wenn das Konsolenfenster automatisch geschlossen wird, prüfen Sie, ob die angegebene Einstellung nicht festgelegt ist.

Gleiches gilt für die neuen Konsolenprojekte von .NET Framework:

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

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

</Project>

Das .NET Framework-Projekt alten Stils schließt die Konsole am Ende weiterhin bedingungslos (ab Visual Studio 16.0.1).

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

1
Vlad

Das Programm wird beendet, sobald die Ausführung abgeschlossen ist. In diesem Fall, wenn Sie return 0;. Dies ist erwartete Funktionalität. Wenn Sie die Ausgabe sehen möchten, führen Sie sie entweder manuell in einem Terminal aus oder legen Sie am Ende des Programms eine Wartezeit fest, damit sie einige Sekunden geöffnet bleibt (mithilfe der Threading-Bibliothek).

0
zellio

dies ist die Antwort async bei der Konsolen-App in C #?

wo immer in der Konsolen-App auch immer, verwenden Sie niemals await, sondern stattdessen theAsyncMethod().GetAwaiter().GetResult();.

beispiel

var result = await HttpClientInstance.SendAsync(message);

wird

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

0
bresleveloper

Hier ist eine Möglichkeit, dies zu tun, ohne Console mit einzubeziehen:

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