我有一个需要调用的非托管函数,它接收一个等待句柄作为参数。 非托管代码在适当的时候会向这个等待句柄发出信号,以通知我的代码一些情况。 我的问题是,我是否需要以某种方式引脚这个等待句柄,以防止GC移动等待句柄?
(伪)代码是这样的。
using (var resetEvent = new AutoResetEvent(false))
{
var iBuffer = Convert.ToUInt32(resetEvent.SafeWaitHandle.DangerousGetHandle().ToInt32());
// Pass iBuffer to unmanaged API function. The unmanaged API passes in the wait handle as a ref uint.
var handles = new[] {resetEvent, _cancellationTokenSource.Token.WaitHandle};
while(WaitHandle.WaitAny(handles) == 0)
{
// do stuff in response to resetEvent being signaled.
}
}
我没有直接传递AutoResetEvent对象 (甚至没有传递 "SafeWaitHandle"), 而是直接传递DangerousGetHandle()返回. 我不清楚返回的'Dangerous'句柄是否真的已经代表了一个非管理资源,因此不需要任何销号?
据我所知,No。
Pinning是需要防止托管内存被移动的。另一方面,一个句柄代表了一些操作系统资源,因此不需要被钉住。
你可能仍然需要注意句柄不会被非托管代码保存,并确保句柄在被非托管代码使用时不会被释放invalidateclosedispose。