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