Если вы хотите, чтобы ваше приложение было открыто, вам нужно что-то сделать, чтобы поддержать его процесс. Приведенный ниже пример является самым простым, который нужно поместить в конец вашей программы:
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();