Se vuoi mantenere aperta la tua applicazione, devi fare qualcosa per mantenere vivo il suo processo. L'esempio seguente è il più semplice, da mettere alla fine del programma:
while (true) ;
Tuttavia, causerà un sovraccarico della CPU, poiché è quindi costretto a scorrere all'infinito.
A questo punto, puoi scegliere di utilizzare la System.Windows.Forms.Application
classe (ma è necessario aggiungere un System.Windows.Forms
riferimento):
Application.Run();
Questo non perde la CPU e funziona correttamente.
Per evitare di aggiungere System.Windows.Forms
riferimenti, è possibile utilizzare un semplice trucco, il cosiddetto spin in attesa , importando System.Threading
:
SpinWait.SpinUntil(() => false);
Anche questo funziona perfettamente e sostanzialmente consiste in un while
ciclo con una condizione negata che viene restituita dal metodo lambda sopra. Perché questa CPU non sovraccarica? Puoi guardare il codice sorgente qui ; comunque, in pratica attende qualche ciclo della CPU prima di ripetere.
È inoltre possibile creare un looper di messaggi, che visualizza i messaggi in sospeso dal sistema e li elabora prima di passare alla successiva iterazione, come segue:
[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;
}
Quindi, puoi eseguire il loop in sicurezza facendo una cosa del genere:
while (true)
ProcessMessageOnce();