如何在异步本机调用时使用DangerousAddRef

时间:2013-10-10 08:42:33

标签: c# .net asynchronous

当调用一个接受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);
        }
    }

0 个答案:

没有答案