Якщо ви хочете, щоб ваша програма відкрита, вам потрібно щось зробити, щоб зберегти її процес. Наведений нижче приклад - найпростіший, який слід розмістити в кінці програми:
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();