c# - 何时/如何注销 RegisteredWaitHandle

标签 c# .net windows threadpool

我正在使用 ThreadPool.UnsafeRegisterWaitForSingleObject(以下简称 RWFSO)异步等待 Semaphore。它返回一个 RegisteredWaitHandle,我无法轻易地 Unregister()。我需要取消注册这些,因为句柄保留对委托(delegate)及其状态对象的引用,而我的进程正在泄漏每个句柄的内存。最终它们确实得到了最终确定,但这花费的时间太长并且给 GC 带来了太大的压力,使我的进程的私有(private)内存使用量膨胀到 1.8GB 范围。我正在发出大量异步请求。

信号量用于控制对HttpWebRequest 的异步实现的访问:BeginGetRequestStreamBeginGetResponse。如果我不使用信号量,它会一直告诉我“线程池中没有足够的空闲线程”,因为它的实现方式很愚蠢。如果我使用像 semaphore.WaitOne() 这样的阻塞原语,那么我的线程池最终会死锁,任何事情都不会取得进展。

RWFSO 返回一个 RegisteredWaitHandle 但这对我的调用线程没有用,因为只有在等待完成时我才需要 Unregister() 这个句柄;我没有取消方案。我不能只将 RegisteredWaitHandle 实例传递给我的委托(delegate)(通过在传递给委托(delegate)的状态对象上设置的带外字段),因为委托(delegate)甚至可以在控制之前在另一个线程上完成从 RWFSO 返回。

我如何安全快速地 Unregister() RegisteredWaitHandle 当且仅当其等待完成时?

最佳答案

只需通过适合您的任何机制将句柄传递给委托(delegate)即可。如果在委托(delegate)执行时句柄为空,则让委托(delegate)自旋等待分配。不要担心所使用的 CPU 时间微不足道,因为您可以将 Thread.Yield 放入循环中。如果它打扰你,你可以使用锁。

或者,您可以取消注册那里的句柄,让 GC 清理少数输掉比赛的句柄。

关于c# - 何时/如何注销 RegisteredWaitHandle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9521527/

相关文章:

c - Qt 中对 NetWkstaUserGetInfo 的 undefined reference ,但在 VS 中有效

c# - 表达式树可能不包含动态操作,但它没有告诉我在哪里

c# - 如何使用正则表达式(c#)识别重复类型的模式

c# - 在项目中使用同一 DLL 的不同版本

c# - 以相反的顺序从字符串中获取值

c# - 我可以复制一个项目的一些引用并将其粘贴到 Visual Studio 中另一个项目的引用吗?

windows - "Official Meteor for Windows Preview"是否支持移动包?

linux - spark standalone 没有 hdfs

c# - 类与结构

c# - 如何获取.NET 6.0 中的时钟序列?