我正在使用ThreadPool.UnsafeRegisterWaitForSingleObject
(此后的rwfso)异步等待Semaphore
。它返回给我一个RegisteredWaitHandle
,我很难Unregister()
。我需要注销这些,因为句柄保留对委托及其状态对象的引用,而我的进程正在使用每个句柄泄漏内存。最终它们确实最终确定下来了,但是这花费了太多的时间,给GC带来了太大的压力,使我的进程的私有内存使用膨胀到了1.8GB的范围。我提出了很多异步请求。
该信号量用于门访问HttpWebRequest
的异步实现:BeginGetRequestStream
和BeginGetResponse
。如果我不使用信号量,它会一直告诉我“线程池中没有足够的空闲线程”,因为它的实现方式很愚蠢。如果我使用像semaphore.WaitOne()
这样的阻塞原语,那么我的线程池最终将陷入僵局,没有任何进展。
rwfso返回一个RegisteredWaitHandle
但这对我的调用线程没有用处,因为我需要Unregister()
这个句柄,只有在等待完成时;我没有取消场景。我不能仅仅将RegisteredWaitHandle
实例传递给我的委托(通过传递给委托的state对象上设置的带外字段),因为委托可以在另一个线程上完成,甚至在rwfso返回控件之前。
当且仅当其等待完成时,如何安全快速地Unregister()
aRegisteredWaitHandle
s?
最佳答案
只要通过任何适合您的机制将句柄传递给委托即可。如果在委托执行时句柄为空,则让委托在等待分配时旋转。不要担心使用的cpu时间太少,因为您可以将Thread.Yield
放入循环中。如果它打扰你,你可以用锁。
或者,您可以注销那里的句柄,并让gc清理少数输掉比赛的句柄。
关于c# - 何时/如何注销RegisteredWaitHandle,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9521527/