关闭控制台时正常退出 window
Graceful exit when closing console window
我正在尝试在点击关闭按钮时正常退出控制台应用程序。
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
我的处理程序被正确调用,但主线程之后没有恢复,所以 "bye" 永远不会发生。如果我改为捕获 CTRL_C_EVENT 并在控制台中点击 ^C,则允许主线程继续并正常退出。有什么方法可以让主线程在控制台关闭时正常退出吗?
我也尝试过使用 std::signal 但它是一样的。适用于 ^C 但不适用于 window close.
感谢乔纳森的提示。
我看到处理程序是在它自己的线程上调用的。如果处理程序 returns 则整个进程被迫退出,所以我们需要给主线程时间让其自行退出。
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
Sleep(20000); // force exit after 20 seconds
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
我认为更好的方法是使用:
if (event == CTRL_CLOSE_EVENT)
{
ExitThread(0);
// return TRUE; // warning C4702: unreachable code
}
ExitThread
将终止调用 ctrl_handler
的线程。这样 ExitProcess
将不会被调用,您的主线程将能够执行所有需要的清理工作。
我正在尝试在点击关闭按钮时正常退出控制台应用程序。
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
我的处理程序被正确调用,但主线程之后没有恢复,所以 "bye" 永远不会发生。如果我改为捕获 CTRL_C_EVENT 并在控制台中点击 ^C,则允许主线程继续并正常退出。有什么方法可以让主线程在控制台关闭时正常退出吗?
我也尝试过使用 std::signal 但它是一样的。适用于 ^C 但不适用于 window close.
感谢乔纳森的提示。
我看到处理程序是在它自己的线程上调用的。如果处理程序 returns 则整个进程被迫退出,所以我们需要给主线程时间让其自行退出。
bool done = false;
BOOL ctrl_handler(DWORD event)
{
if (event == CTRL_CLOSE_EVENT) {
done = true;
Sleep(20000); // force exit after 20 seconds
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);
while (!done)
do_stuff();
cleanup();
cout << "bye";
}
我认为更好的方法是使用:
if (event == CTRL_CLOSE_EVENT)
{
ExitThread(0);
// return TRUE; // warning C4702: unreachable code
}
ExitThread
将终止调用 ctrl_handler
的线程。这样 ExitProcess
将不会被调用,您的主线程将能够执行所有需要的清理工作。