c# - ThreadPool.RegisterWaitForSingleObject 是否阻塞当前线程或线程池线程?

标签 c# .net multithreading clr

来自阅读the documentation of the ThreadPool.RegisterWaitForSingleObject方法,不清楚是否:

  1. 它在等待 EventWaitHandle 时阻塞当前线程,然后在线程池线程上委托(delegate) WaitOrTimerCallback,或者

  2. 它委托(delegate)线程池线程等待等待句柄,然后在等待句柄发出信号后在同一线程上执行 WaitOrTimerCallback

  3. 它阻塞当前线程,当等待句柄发出信号时,它调用当前线程上的 WaitOrTimerCallback。但这将是 WaitHandle.WaitOne() 的等效功能。而且,它根本不会涉及线程池。

这三者中的哪一个?

最佳答案

以上都不是,2)最接近。确切的细节非常复杂,大部分代码都隐藏在 CLR 中,并且它在 .NET 版本之间发生了变化。你可以看看当前版本in the CoreCLR source , 我将给出 10,000 英尺的 View 。

关键是它不阻塞,工作由专用的非托管线程完成。在源代码中称为“等待线程”,它使用 WaitForMultipleObjects() winapi 函数来等待所有已注册的等待。如果没有(左)它只是 sleep 。如果等待列表发生变化,线程会被 QueueUserApc() 唤醒,以便它可以使用更新后的列表恢复等待。

一旦等待对象之一收到信号,它就会使用 ThreadPool.QueueUserWorkItem() 在线程池线程上调用回调委托(delegate)目标。如果 executeOnlyOnce 参数为真,则等待句柄将从列表中删除。它很快就会恢复等待 WFMO。线程永远不会结束。

executeOnlyOnce 参数很重要,顺便说一句,如果您传递 false 并使用 ManualResetEvent,就会很热闹。由 MRE 的 Set() 方法触发的线程爆炸是一个值得观察的有趣工件:) 当您启用非托管调试时,您可以在调试器的 Debug > Windows > Threads 中看到等待线程。然而,它没有一个有趣的名字。

关于c# - ThreadPool.RegisterWaitForSingleObject 是否阻塞当前线程或线程池线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37499541/

相关文章:

java - 通知不起作用..永远等待线程 Java

c# - 使用 2 个其他数组对数组进行排序

c# - 解压错误/压缩错误

c# - 使用 IronPython 针对 .NET 程序集进行编码的问题,特别是在 app.config 方面

.net - C4.5 算法如何处理连续数据?

python - 在退出 Python 程序之前等待所有守护线程完成的简单方法?

c# - 无法隐式转换类型 'Newtonsoft.Json.Linq.JObject'

c# - 在 C++ 函数执行后使用 GCHandle 崩溃将大型结构数组从 C# unity 脚本传递到 C++ dll

c# - 在 Azure Service Fabric 上设置 TCP

java - 多线程 Android 游戏上的图像不稳定