MSDN 의 가이드를 따라 C #을 공부하고 있습니다.
이제 예제 1 ( 여기 MSDN에 대한 링크)을 시도했는데 문제가 발생했습니다. 출력이 표시되면 콘솔 창이 즉시 닫히는 이유는 무엇입니까?
using System;
public class Hello1
{
public static int Main()
{
Console.WriteLine("Hello, World!");
return 0;
}
}
답변
여기서 문제는 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
답변
사용하는 대신
Console.Readline()
Console.Read()
Console.ReadKey()
Ctrl+를 사용하여 프로그램을 실행할 수 있습니다 F5(Visual Studio에있는 경우). 그러면 Visual Studio는 키를 누를 때까지 콘솔 창을 열어 둡니다.
참고 :이 접근 방식에서는 코드를 디버깅 할 수 없습니다.
답변
디버그 모드에서 닫기를 원하지 않는 이유는 변수 등의 값을보고 싶기 때문이라고 가정합니다. 따라서 주 함수의 닫기 “}”에 중단 점을 삽입하는 것이 가장 좋습니다. . 디버그 할 필요가없는 경우 Ctrl-F5가 가장 좋은 옵션입니다.
답변
이것은 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();
}
}
답변
프로그램이 종료되는 것을 막지 못하기 때문에 프로그램이 즉시 종료됩니다. 프로그램이 닫히지 않도록 중단 점을 삽입 return 0;
하거나 Console.Read();
앞에 추가하십시오 return 0;
.
답변
파티에 조금 늦었지만 .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/
답변
애플리케이션을 계속 열어 두려면 프로세스를 유지하기 위해 무언가를해야합니다. 아래 예제는 프로그램 끝에 넣는 가장 간단한 예제입니다.
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();
