該解決方案需要不安全的代碼(使用/unsafe
開關進行編譯),但直接獲取指向內存的指針;那麼可以使用Marshal.Copy
。這比.NET框架提供的方法要快得多。
// assumes part of a class where _view is a MemoryMappedViewAccessor object
public unsafe byte[] ReadBytes(int offset, int num)
{
byte[] arr = new byte[num];
byte *ptr = (byte*)0;
this._view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
Marshal.Copy(IntPtr.Add(new IntPtr(ptr), offset), arr, 0, num);
this._view.SafeMemoryMappedViewHandle.ReleasePointer();
return arr;
}
public unsafe void WriteBytes(int offset, byte[] data)
{
byte* ptr = (byte*)0;
this._view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
Marshal.Copy(data, 0, IntPtr.Add(new IntPtr(ptr), offset), data.Length);
this._view.SafeMemoryMappedViewHandle.ReleasePointer();
}
您應該使用一個關鍵的執行塊和嘗試,終於以確保ReleasePointer運行,即使在Marshal.Copy拋出異常。 –
好答案=)確實,分析顯示託管包裝比使用不安全指針訪問映射內存慢30倍。 – 2013-04-02 00:01:39
@MattHowells我同意。我讀過CER可能會影響性能,但它似乎可以忽略不計(至少在一個受控測試中)。無論性能如何,它都是正確的使用模式,正如此處的「備註」中所述; https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safebuffer.acquirepointer(v=vs.110).aspx – LaFleur