출력이 표시되면 콘솔 창이 즉시 닫히는 이유는 무엇입니까?


159

MSDN 의 가이드를 따라 C #을 공부하고 있습니다.

이제 예제 1 ( 여기 MSDN에 대한 링크)을 시도했는데 문제가 발생했습니다. 출력이 표시되면 콘솔 창이 즉시 닫히는 이유는 무엇입니까?

using System;

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

콘솔로 열어 볼 수 있습니다. 콘솔에 끌어다 놓고 "Enter"를 누르십시오. 나는 그것의 EXE 파일을 가정합니다.
Sajidur Rahman

외부 프로세스에 의해 시작된 명령 줄 프로그램을 디버그하려는 경우 다음 질문을 참조하십시오. stackoverflow.com/a/23334014/3195477
UuDdLrLrSs

답변:


272

여기서 문제는 Hello World 프로그램이 표시되고 즉시 종료된다는 것입니다.
왜 그런 겁니까?

끝났 으니까. 콘솔 응용 프로그램이 실행을 완료하고 해당 main메서드 에서 돌아 오면 연결된 콘솔 창이 자동으로 닫힙니다. 이것은 예상 된 동작입니다.

디버깅을 위해 열어 두려면 앱을 종료하고 창을 닫기 전에 키 누름을 기다리도록 컴퓨터에 지시해야합니다.

Console.ReadLine방법은 그 일의 한 가지 방법입니다. 이 줄을 코드 끝에 ( return문 바로 앞 ) 추가하면 애플리케이션이 종료하기 전에 키를 누를 때까지 기다리게됩니다.

또는 Visual Studio 환경에서 Ctrl+ F5를 눌러 연결된 디버거없이 응용 프로그램을 시작할 수 있지만이 경우 응용 프로그램을 작성할 때 원하는대로 디버깅 기능을 사용할 수 없다는 명백한 단점이 있습니다.

가장 좋은 절충안은 아마도 Console.ReadLine전 처리기 지시문에 래핑하여 응용 프로그램을 디버깅 할 때만 메서드 를 호출하는 것입니다 . 다음과 같은 것 :

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

잡히지 않은 예외가 발생한 경우 창을 열어두기를 원할 수도 있습니다. 당신은 넣을 수 그렇게하려면 Console.ReadLine();A의 finally블록 :

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

18
또는 Console.ReadKey ();를 사용할 수 있습니다.
PlantationGator

57
개인적으로 나는 if (System.Diagnostics.Debugger.IsAttached) Console.ReadLine();.
Sameer Singh

5
디버깅하지 않고 실행하면 그 동작이 변경되는 이유는 무엇입니까? 더 정확한 경험이되어야한다고 생각할 것입니다.
Kyle Delaney 2017 년

@SameerSingh 바이너리로 컴파일되는 불필요한 코드 한 줄이 더 있습니다. 저는 실제로이 전 처리기 접근 방식을 선호합니다.
Joel

@Joel 요즘 왜 우리가 일반적으로 그것에 관심을 가져야합니까?
Alex

68

사용하는 대신

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

Ctrl+를 사용하여 프로그램을 실행할 수 있습니다 F5(Visual Studio에있는 경우). 그러면 Visual Studio는 키를 누를 때까지 콘솔 창을 열어 둡니다.

참고 :이 접근 방식에서는 코드를 디버깅 할 수 없습니다.


안녕하세요 사용자. 저는 일반적으로 VS 및 C #의 새로운 사용자입니다. Ctrl + F5단순히 예쁘다고 다르게하는 것은 무엇입니까 Start?
theGreenCabbage 2013

불행히도 때로는 예상대로 작동하지 않습니다.
MaikoID

2
문제의 원인은 프로그램이 중지되면 창이 자동으로 터미널 창을 닫는 것입니다. 다른 시스템은 창을 자동으로 열어 둡니다. 이것은 프로그램을 실행하는 훨씬 더 좋은 방법입니다. ReadKey, Read 또는 ReadLine을 다른 콘솔 응용 프로그램 및 배관과 함께 사용하는 것을 방지하므로이 항목에 대해 ReadKey, Read 또는 ReadLine을 사용하지 마십시오.
실시간

14

디버그 모드에서 닫기를 원하지 않는 이유는 변수 등의 값을보고 싶기 때문이라고 가정합니다. 따라서 주 함수의 닫기 "}"에 중단 점을 삽입하는 것이 가장 좋습니다. . 디버그 할 필요가없는 경우 Ctrl-F5가 가장 좋은 옵션입니다.


놀랍게도 다른 답변은 이것을 제안하지 않았습니다. 질문이 생성 된 후 너무 늦게 추가되는 새로운 옵션이있는 답변은 드뭅니다.
Scott Chamberlain

13

이것은 CtrlF5또는에 대해 동일하게 작동합니다 F5. Main방법 종료 직전에 놓습니다.

using System.Diagnostics;

private static void Main(string[] args) {

  DoWork();

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

7
참고로 마지막 줄은 Console.ReadKey()아무 키나 Console.ReadLine()입력해야하며 Enter 키 를 누를 때까지 기다립니다
Chris

6

프로그램이 종료되는 것을 막지 못하기 때문에 프로그램이 즉시 종료됩니다. 프로그램이 닫히지 않도록 중단 점을 삽입 return 0;하거나 Console.Read();앞에 추가하십시오 return 0;.


6

파티에 조금 늦었지만 .NET Core 프로젝트 용 Visual Studio 2019에서는 기본적으로 콘솔이 자동으로 닫히지 않습니다. 도구 → 옵션 → 디버깅 → 일반 → 디버깅 중지시 콘솔 자동 닫기 메뉴를 통해 동작을 구성 할 수 있습니다. 콘솔 창이 자동으로 닫히면 언급 된 설정이 설정되지 않았는지 확인하십시오.

.NET Framework 새 스타일 콘솔 프로젝트에도 동일하게 적용됩니다.

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

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

</Project>

이전 스타일의 .NET Framework 프로젝트는 여전히 끝에서 콘솔을 무조건 닫습니다 (Visual Studio 16.0.1 기준).

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


...이 옵션은 VS2017 15.9.4에서 나를 위해 사용할 수 있지만 내 그물 코어 2.1 콘솔 응용 프로그램에 대해 작동하지 않습니다
user1073075

@ user1073075 : 이상합니다. 기능이 다른 대상에서도 작동합니까?
Vlad

아니요. .NET 프레임 워크 콘솔 앱으로 시도했지만 여전히 작동하지 않았습니다. (다른 시스템에 VS2019를 설치했는데 작동합니다. VS17 15.9.4의 버그 일 수 있습니다.)
user1073075

2019에서는 이제 WPF 프로젝트에서도 작동합니다 : pastebin.com/FpAeV0cW . 하지만 .NET Core 3을 설치해야합니다.
Vlad

5

애플리케이션을 계속 열어 두려면 프로세스를 유지하기 위해 무언가를해야합니다. 아래 예제는 프로그램 끝에 넣는 가장 간단한 예제입니다.

while (true) ;

그러나 CPU가 무한히 반복해야하므로 과부하가 발생합니다.

이 시점에서 System.Windows.Forms.Application클래스 를 사용하도록 선택할 수 있지만 System.Windows.Forms참조 를 추가해야합니다 .

Application.Run();

이것은 CPU 누출이 없으며 성공적으로 작동합니다.

추가 피하기 위해 System.Windows.Forms참조를, 당신은 간단한 트릭, 소위 사용할 수 있습니다 스핀 대기를 가져 오기 System.Threading:

SpinWait.SpinUntil(() => false);

이것은 또한 완벽하게 작동하며 기본적으로 while위의 람다 메서드에 의해 반환되는 부정 조건이 있는 루프 로 구성됩니다 . CPU가 과부하되지 않는 이유는 무엇입니까? 여기 에서 소스 코드를 볼 수 있습니다 . 어쨌든, 기본적으로 반복하기 전에 CPU주기를 기다립니다.

다음과 같이 시스템에서 보류중인 메시지를 엿보고 다음 반복으로 전달하기 전에 각 메시지를 처리하는 메시지 루퍼를 만들 수도 있습니다.

[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();

이것이 CPU 누수인지 아닌지는 모르겠지만; 성공적으로 작동합니다. 감사합니다.
Mumin Ka

4

또는 다음 코드를 사용하여 마감을 지연 할 수 있습니다.

System.Threading.Thread.Sleep(1000);

(가) 주 Sleep(밀리 초)을 사용하고 있습니다.


4

또 다른 방법은 Debugger.Break()Main 메서드에서 반환하기 전에 사용 하는 것입니다.


이 스위치는 디버거 창으로 다시 초점을 맞추고 잠재적으로 콘솔 창의 내용을 숨 깁니다.
Stephen Turner

3

코드가 완료되었습니다. 계속하려면 다음을 추가해야합니다.

Console.ReadLine();

또는

Console.Read();

3

Console.Read (); 사용 프로그램이 닫히지 않도록하려면 Console.Read();return 문 앞에 코드 를 추가해야합니다. 그렇지 않으면 연결할 수없는 코드가됩니다.

    Console.Read(); 
    return 0; 

콘솔을 확인하십시오.


3

Add Read출력을 표시하는 방법입니다.

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

1

다음은 관련없이 수행하는 방법입니다 Console.

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

0

프로그램은 실행이 완료되는 즉시 닫힙니다. 이 경우 return 0;. 이것은 예상되는 기능입니다. 출력을 보려면 터미널에서 수동으로 실행하거나 프로그램 끝에서 대기를 설정하여 몇 초 동안 열려 있도록합니다 (스레딩 라이브러리 사용).


0

이것은 C #의 콘솔 앱에서 비동기 답변 입니까?

콘솔 앱의 모든 곳에서 사용 await하지 않고 대신 theAsyncMethod().GetAwaiter().GetResult();,

var result = await HttpClientInstance.SendAsync(message);

된다

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


-3

프로그램에서 값을 입력하고 계속해야하는 것처럼 계속하려면 Enter 키를 눌러야하는 경우 새 double 또는 int를 추가하고 retunr (0) 앞에 write를 입력합니다. scanf_s ( "% lf", & the 변수);


1
이것은 C # 질문입니다.
Wai Ha Lee

-3

나는 항상 콘솔 애플리케이션에 다음 문장을 추가합니다.

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

이렇게하면 콘솔 응용 프로그램을 통해 다른 개념을 실험 할 때 도움이됩니다.

Ctr + F5 는 콘솔을 유지하지만 디버그 할 수 없습니다! 내가 실제로 작성한 모든 콘솔 애플리케이션은 항상 비대화 형이며 TWS 또는 CA Workstation과 같은 스케줄러에 의해 트리거되며 이와 같은 것이 필요하지 않습니다.


-3

다른 사람들이 말하는 것을 단순화하려면 :을 사용하십시오 Console.ReadKey();.

이렇게하면 프로그램이 사용자가 키보드의 일반 키를 누르기를 기다립니다.

출처 : 콘솔 애플리케이션 용 프로그램에서 사용합니다.


-3

입력을 호출하는 것만으로도 아주 간단한 방법으로 해결할 수 있습니다. 그러나를 누르면 Enter본체가 다시 사라집니다. 이것을 사용 Console.ReadLine();하거나Console.Read();


-4

리턴 0 앞에 다음을 추가하십시오.

system("PAUSE");  

이것은 창을 닫기 위해 키를 누르는 라인을 인쇄합니다. Enter 키를 누를 때까지 창을 계속 유지합니다. 학생들에게 모든 프로그램에 추가하도록합니다.


1
그게 전부는 C ++에
곤 칼로 가리

-14

내 관심사에 따르면, OUTPUT OF CONSOLE APPLICATION을 안정시키고 싶다면 출력 디스플레이 USE가 끝날 때까지 레이블 : After the MainMethod 및 goto 레이블; 프로그램 종료 전

프로그램에서.

예 :

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

    // Snippet of code

    goto label;
}

2
이렇게하면 포스터 프로그램이 "Hello, World!"를 계속 인쇄합니다. 여러 번
DavidPostill

1
예수 그리스도, gotoC #에서 진술이 허용되는 것을 몰랐습니다 .
Ch3shire
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.