在调用采用 IntPtr 的本机函数时,我了解如何使用 Sync 本机函数进行操作。
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void Operation(SafeHandle handle)
{
var mustReleaseSafeHandle = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
handle.DangerousAddRef(ref mustReleaseSafeHandle);
if (mustReleaseSafeHandle) WinAPI.Operation(handle.DangerousGetHandle());
}
finally
{
if (mustReleaseSafeHandle) handle.DangerousRelease();
}
}
当本机函数异步时,如何确保 DangerousRelease 发生?
这是我异步尝试添加更多上下文的伪示例,正如 Hans Passant 建议的那样。
public static unsafe void Operation(SafeHandle fileHandle, SafeHandle nativeMemoryHandle, int offset)
{
var mustReleaseSafeHandle = false;
var ioCompletionCallback = new IOCompletionCallback((code, bytes, overlap) =>
{
if (mustReleaseSafeHandle) nativeMemoryHandle.DangerousRelease();
Overlapped.Free(overlap);
});
var overlapped = new Overlapped();
var nativeOverlapped = overlapped.Pack(ioCompletionCallback, null);
nativeMemoryHandle.DangerousAddRef(ref mustReleaseSafeHandle);
if (mustReleaseSafeHandle)
{
var memoryStartLocation = IntPtr.Add(nativeMemoryHandle.DangerousGetHandle(), offset);
if (!WinAPI.Operation(fileHandle, memoryStartLocation, offset, nativeOverlapped))
{
nativeMemoryHandle.DangerousRelease();
Overlapped.Free(nativeOverlapped);
}
}
else
{
Overlapped.Free(nativeOverlapped);
}
}