ThreadPool.RegisterWaitForSingleObject是否阻塞当前线程或线程池线程? [英] Does ThreadPool.RegisterWaitForSingleObject block the current thread or a thread-pool thread?

查看:200
本文介绍了ThreadPool.RegisterWaitForSingleObject是否阻塞当前线程或线程池线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过阅读 <$的文档c $ c> ThreadPool.RegisterWaitForSingleObject 方法,尚不清楚是否:

From reading the documentation of the ThreadPool.RegisterWaitForSingleObject method, it is not clear whether:


  1. 它在等待 EventWaitHandle 时阻塞当前线程,然后在线程池线程上调试 WaitOrTimerCallback ,或者

  1. It blocks the current thread while waiting on the EventWaitHandle and then commissions the WaitOrTimerCallback on a thread pool thread, or

它委托线程池线程在等待句柄上等待,然后在同一线程上执行 WaitOrTimerCallback 一旦发出了等待句柄信号。

It commissions a thread pool thread to wait on the wait handle and then on that same thread execute the WaitOrTimerCallback once the wait handle has been signaled.

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

It blocks the current thread and when the wait handle is signaled, it calls the WaitOrTimerCallback on the current thread. But this would be the equivalent functionality of WaitHandle.WaitOne(). Also, it would not involve the thread pool at all.

这三个函数中的哪个?

推荐答案

以上都不是,2)最接近。确切的细节令人费解,大多数代码都埋在CLR中,并且在.NET版本中已更改。您可以在CoreCLR来源中查看当前版本,我将给出10,000英尺的视图。

It is none of the above, 2) is closest. The exact details are pretty convoluted, most of the code is buried in the CLR and it has changed across .NET versions. You can have a look-see at the current version in the CoreCLR source, I'll give the 10,000 feet view.

关键是它不会阻塞,工作是由专用的非托管线程完成的。在源代码中称为等待线程,它使用WaitForMultipleObjects()winapi函数来等待所有已注册的等待。如果没有(左),它将进入睡眠状态。如果等待列表更改,则可以通过QueueUserApc()唤醒该线程,以便可以使用更新的列表继续等待。

Key is that it doesn't block, the work is done by a dedicated unmanaged thread. Called the "wait thread" in the source code, it uses the WaitForMultipleObjects() winapi function to wait on all registered waits. If there is none (left) it just sleeps. The thread is woken up from either by a QueueUserApc() if the wait list changes so it can resume waiting with an updated list.

一旦发出一个等待对象信号,它使用ThreadPool.QueueUserWorkItem()在线程池线程上调用回调委托目标。如果 executeOnlyOnce 参数为true,则从列表中删除等待句柄。并且它可以快速恢复与WFMO的等待。线程永远不会结束。

Once one of the wait objects get signaled, it uses ThreadPool.QueueUserWorkItem() to invoke the callback delegate target on a threadpool thread. If the executeOnlyOnce argument was true then the wait handle is removed from the list. And it quickly resumes waiting with WFMO. The thread never ends.

executeOnlyOnce 参数很重要,如果您通过 false ,然后使用ManualResetEvent。由MRE的Set()方法触发的线程爆炸是一个有趣的观察对象:)启用非托管调试时,您可以在调试器的调试> Windows>线程中看到等待线程。但是,它的名字并不有趣。

The executeOnlyOnce argument is important btw, hilarity ensues if you pass false and you use a ManualResetEvent. The thread explosion triggered by the MRE's Set() method is an interesting artifact to observe :) You can see the wait thread in the debugger's Debug > Windows > Threads when you enable unmanaged debugging. It doesn't have an interesting name however.

这篇关于ThreadPool.RegisterWaitForSingleObject是否阻塞当前线程或线程池线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆