我正在使用ThreadPool.UnsafeRegisterWaitForSingleObject(此后的rwfso)异步等待Semaphore。它返回给我一个RegisteredWaitHandle,我很难Unregister()。我需要注销这些,因为句柄保留对委托及其状态对象的引用,而我的进程正在使用每个句柄泄漏内存。最终它们确实最终确定下来了,但是这花费了太多的时间,给GC带来了太大的压力,使我的进程的私有内存使用膨胀到了1.8GB的范围。我提出了很多异步请求。
该信号量用于门访问HttpWebRequest的异步实现:BeginGetRequestStreamBeginGetResponse。如果我不使用信号量,它会一直告诉我“线程池中没有足够的空闲线程”,因为它的实现方式很愚蠢。如果我使用像semaphore.WaitOne()这样的阻塞原语,那么我的线程池最终将陷入僵局,没有任何进展。
rwfso返回一个RegisteredWaitHandle但这对我的调用线程没有用处,因为我需要Unregister()这个句柄,只有在等待完成时;我没有取消场景。我不能仅仅将RegisteredWaitHandle实例传递给我的委托(通过传递给委托的state对象上设置的带外字段),因为委托可以在另一个线程上完成,甚至在rwfso返回控件之前。
当且仅当其等待完成时,如何安全快速地Unregister()aRegisteredWaitHandles?

最佳答案

只要通过任何适合您的机制将句柄传递给委托即可。如果在委托执行时句柄为空,则让委托在等待分配时旋转。不要担心使用的cpu时间太少,因为您可以将Thread.Yield放入循环中。如果它打扰你,你可以用锁。
或者,您可以注销那里的句柄,并让gc清理少数输掉比赛的句柄。

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

10-10 14:58