我在Windows 7上有一個命令行應用程序。它主要由一個無限循環組成。當我點擊命令行控制檯窗口的關閉按鈕時,它似乎立即死亡。但是,我在析構函數中關閉了一個SQLite數據庫連接,所以我擔心數據庫可能會損壞。即使不是,我希望能夠正確地終止我的對象(也許通過寫入文件,記錄等)。當我點擊控制檯上的關閉按鈕時,爲什麼不會調用析構函數?
我可以以某種方式確保我的析構函數被調用嗎?如果我關上窗戶,會發生什麼?是否有一種「軟」的方式來關閉程序?
我在Windows 7上有一個命令行應用程序。它主要由一個無限循環組成。當我點擊命令行控制檯窗口的關閉按鈕時,它似乎立即死亡。但是,我在析構函數中關閉了一個SQLite數據庫連接,所以我擔心數據庫可能會損壞。即使不是,我希望能夠正確地終止我的對象(也許通過寫入文件,記錄等)。當我點擊控制檯上的關閉按鈕時,爲什麼不會調用析構函數?
我可以以某種方式確保我的析構函數被調用嗎?如果我關上窗戶,會發生什麼?是否有一種「軟」的方式來關閉程序?
控制檯應用程序沒有消息循環,你會要求退出然而,Windows將你的能力來註冊一個函數來接收一些通知您可能需要處理。其中之一是關閉通知。
首先聲明,Windows就會調用爲此與原型由HandlerRoutine給出一個函數:
BOOL WINAPI ConsoleHandlerRoutine(DWORD dwCtrlType) {
if (CTRL_CLOSE_EVENT == dwCtrlType) {
return TRUE;
}
return FALSE;
}
現在註冊該功能,使用SetControlCtrlHandler,你開始循環之前:
int main(int argc, char* argv[])
{
if (FALSE == SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE)) {
// Cannot register your handler? Check GetLastError()
}
while (true)
{
// This is your loop
}
return 0;
}
完成了。你可以顯式刪除你想要處理的對象,或者簡單地設置一個標誌來打破你的無限循環。
請注意,您將收到更多的事件(Windows關機CTRL_SHUTDOWN_EVENT
,用戶註銷CTRL_LOGOFF_EVENT
,用戶突破CTRL_C_EVENT
,收盤CTRL_CLOSE_EVENT
),處理你需要/想什麼。
...其實我不確定你可以設置一個標誌,你不必在退出ConsoleHandlerRoutine之前完成清理嗎? –
@HarryJohnston:是的。如果'Handler'返回TRUE,則進程立即終止。如果它返回FALSE,則調用下一個註冊的Handler,直到返回「TRUE」或達到默認的「Handler」,在任何一種情況下,該過程都會終止。你必須考慮到'Handler'是在它自己的線程環境中調用的,所以確保它的代碼是線程安全的。 –
我想在很多情況下,它對於處理程序例程來說是最簡單的,用於設置一個標誌,然後在主線程終止該進程之前一直睡眠。 –