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