7

我创建了一个 C# 控制台应用程序来处理Ctrl-C通过订阅 Console.CancelKeyPress 事件。当我执行(调试版本)应用程序时,进程中已经创建了 14 个线程。当我按下Ctrl-C创建一个新的第 15 个线程并调用我的处理程序。我使用来自 sysinternals 的进程资源管理器来查看进程的状态。

我很想知道消息如何传递到进程以及如何创建附加线程的内部Ctrl结构C?我想,即使我不订阅事件,它仍然会创建一个额外的线程并退出进程。处理的默认机制如何Ctrl-C为应用程序设置。

我是一名 .net 开发人员,但想了解 Windows 操作系统如何在后台工作。以上问题只是出于对学习windows操作系统的好奇。

4

2 回答 2

3

当 Windows 需要通知一个外部事件的控制台程序时,没有窗口消息循环来发送通知,因此 Windows 将在目标进程中创建一个线程来执行任何定义的回调函数。CTRL+C 事件的默认处理程序只调用ExitProcess,但挂钩CancelKeyPress事件会使用处理程序函数调用 Win32SetConsoleCtrlHandler函数。

处理函数的文档解释了它是如何工作的:

与 SetConsoleCtrlHandler 函数一起使用的应用程序定义的函数。控制台进程使用此函数来处理进程接收到的控制信号。当接收到信号时,系统在进程中创建一个新线程来执行函数。

请注意,Windows 注入到您的进程中的线程具有相当小的堆栈,因此 CLR 处理程序例程实际上将 Threadpool 工作项排队以执行您的事件处理程序。这意味着 Windows 注入的线程工作线程都可能被创建,导致您在处理 CTRL+C 事件期间看到最多 2 个额外的线程。

于 2011-12-04T17:10:00.673 回答
1

是的,Windows 启动一个线程来调用由SetConsoleCtrlHandler()注册的处理程序。它由名为 ControlCHooker 的小型内部帮助器类的 Hook() 方法调用。由 Cancel.CancelKeyPress 事件的 add() 访问器调用。Windows 回调使您的事件处理程序运行。

像 Reflector 或 ILSpy 这样好的反汇编程序以及参考源可以帮助您发现这些实现细节。

于 2011-12-04T16:48:23.453 回答