Почему окно консоли закрывается сразу после того, как отображается мой вывод? - PullRequest
147 голосов
/ 15 января 2012

Я изучаю C #, следуя инструкциям в MSDN .

Теперь я только что попробовал Пример 1 ( здесь - это ссылка на MSDN ), и я столкнулся с проблемой: почему консоль закрытие окна сразу после того, как отобразился мой вывод?

using System;

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

Ответы [ 21 ]

251 голосов
/ 15 января 2012

проблема здесь в том, что их программа Hello World появляется, а затем сразу закрывается.
почему это?

Поскольку оно завершено. Когда консольные приложения завершают выполнение и возвращаются из метода main, соответствующее окно консоли автоматически закрывается. Это ожидаемое поведение.

Если вы хотите, чтобы он оставался открытым для целей отладки, вам нужно будет дать компьютеру команду подождать нажатия клавиши, прежде чем завершать работу приложения и закрывать окно.

Метод Console.ReadLine является одним из способов сделать это. Добавление этой строки в конец вашего кода (непосредственно перед оператором return) приведет к тому, что приложение будет ждать, пока вы нажмете клавишу, прежде чем выйти.

В качестве альтернативы вы можете запустить приложение без отладчика, нажав Ctrl + F5 в среде Visual Studio, но это имеет очевидный недостаток: функции отладки, которые вы, вероятно, захотите использовать при написании приложения.

Наилучшим компромиссом, вероятно, является вызов метода Console.ReadLine только при отладке приложения путем помещения его в директиву препроцессора. Что-то вроде:

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

Возможно, вы также захотите, чтобы окно оставалось открытым, если было выбрано неперехваченное исключение. Для этого вы можете поместить Console.ReadLine(); в блок finally:

#if DEBUG
    try
    {
        //...
    }
    finally
    {
        Console.WriteLine("Press enter to close...");
        Console.ReadLine();
    }
#endif
62 голосов
/ 09 сентября 2013

Вместо использования

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

вы можете запустить вашу программу, используя Ctrl + F5 (если вы находитесь в Visual Studio). Затем Visual Studio будет держать окно консоли открытым, пока вы не нажмете клавишу.

Примечание: Вы не можете отлаживать свой код в этом подходе.

13 голосов
/ 22 марта 2015

То же самое происходит для Ctrl F5 или F5 .Поместите непосредственно перед завершением Main метода.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

  if (Debugger.IsAttached) {
    Console.WriteLine("Press any key to continue . . .");
    Console.ReadLine();
  }
}
10 голосов
/ 18 февраля 2016

Я предполагаю, что причина, по которой вы не хотите, чтобы он закрывался в режиме отладки, заключается в том, что вы хотите посмотреть на значения переменных и т. Д. Поэтому, вероятно, лучше всего просто вставить точку останова в закрывающий "}"основная функция.Если вам не нужно отлаживать, то Ctrl-F5 - лучший вариант.

6 голосов
/ 15 января 2012

Программа немедленно закрывается, потому что ничто не мешает ей закрыться. Вставьте точку останова на return 0; или добавьте Console.Read(); перед return 0;, чтобы предотвратить закрытие программы.

4 голосов
/ 24 марта 2015

Другой способ - использовать Debugger.Break() перед возвратом из метода Main

4 голосов
/ 03 февраля 2018

Если вы хотите, чтобы ваше приложение было открыто, вам нужно что-то сделать, чтобы сохранить его процесс живым. Ниже приведен простейший пример, который нужно поместить в конец вашей программы:

while (true) ;

Тем не менее, это вызовет перегрузку ЦП, поскольку поэтому он вынужден бесконечно повторяться.

На этом этапе вы можете выбрать System.Windows.Forms.Application класс (но для этого необходимо добавить System.Windows.Forms ссылку):

Application.Run();

Это не пропускает процессор и работает успешно.

Чтобы избежать добавления ссылки System.Windows.Forms, вы можете использовать простой трюк, так называемое ожидание вращения , импортирующее System.Threading:

SpinWait.SpinUntil(() => false);

Это также отлично работает и состоит в основном из итератора while с отрицательным условием, которое возвращается вышеприведенным лямбда-методом. Почему это не перегрузка процессора? Вы можете посмотреть исходный код здесь ; в любом случае, он в основном ожидает некоторый цикл процессора, чтобы сохранить выполнение команд.

Также можно выбрать создание зацикливателя сообщений, который просматривает ожидающие сообщения и обрабатывает каждое из них, прежде чем перейти к следующей итерации:

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

Тогда вы можете безопасно выполнить цикл, выполнив что-то вроде этого:

while (true)
    ProcessMessageOnce();

Еще лучше, вы можете смешать два последних решения, заменив итератор while вызовом SpinWait.SpinUntil:

SpinWait.SpinUntil(ProcessMessageOnce);
4 голосов
/ 07 декабря 2014

Кроме того, вы можете отложить закрытие, используя следующий код:

System.Threading.Thread.Sleep(1000);

Обратите внимание, что Sleep использует миллисекунды.

3 голосов
/ 15 января 2012

Использовать Console.Read ();чтобы предотвратить закрытие программы, но убедитесь, что вы добавили код Console.Read(); перед оператором возврата, иначе это будет недоступный код.

    Console.Read(); 
    return 0; 

отметьте это Консоль. Читать

3 голосов
/ 15 января 2012

Добавьте метод Read, чтобы показать вывод.

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