Memory-mapped file
MMFMemory<T>.CreateNew(mapName, elementCount, access, options, inheritability) creates an inter-process shareable but non-filesystem accessible memory-mapped file.
using IMemory<byte> memory = MMFMemory<byte>.CreateNew(mapName: "name", elementCount: 1000L);
MMFMemory<T>.OpenView(mmf) creates memory access from a mmf handle.
using MemoryMappedFile mmf = MemoryMappedFile.CreateNew("name", 1024L, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.Inheritable);
using IMemory<byte> memory = MMFMemory<byte>.OpenView(mmf);
MMFMemory<T>.CreateFromFile(path, fileMode, mapName?, elementCount, access) open-or-creates a file and memory view.
using IMemory<byte> memory = MMFMemory<byte>.CreateFromFile("file.tmp", FileMode.Create, "name", 1024L);
new MMFMemory<T>(pointer, count) creates memory access to pointer region.
long elementCount = 1_000_000;
long byteCount = elementCount * PointerMemory<long>.ByteSizeOfT;
using MemoryMappedFile mmf = MemoryMappedFile.CreateNew(null, byteCount, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.Inheritable);
using MemoryMappedViewAccessor view = mmf.CreateViewAccessor(0, byteCount, MemoryMappedFileAccess.ReadWrite);
byte* ptr = default!;
view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
using MMFMemory<long> memory = new MMFMemory<long>(ptr, byteCount).AttachDisposable(view);
for (long ix = 0L; ix < memory.Count; ix++) memory[ix] = ix;
Concurrency
Memory-mapped files can be read and written concurrently from different threads.
For dispose considerations, .AttachDisposable(action) attaches a post-dispose action.
using IMemory<byte> memory =
MMFMemory<byte>.CreateNew(mapName: null, elementCount: 1000L)
.AttachDisposable(() => { });
.IsDisposeCalled, .IsDisposing, .IsDisposed evaluates different dispose stages.
using var memory = MMFMemory<byte>.CreateNew(mapName: null, elementCount: 1000L);
bool a = memory.IsDisposeCalled;
bool b = memory.IsDisposing;
bool c = memory.IsDisposed;
.BelateDispose() creates a handle that postpones dispose.
using IDisposable postponeDispose = ((IDisposeBelatable)memory).BelateDispose();
Full Example
Full example
using System.IO.MemoryMappedFiles;
using Avalanche.Memory;
using Avalanche.Utilities;
public class mmfmemory
{
public static void Run()
{
{
// <01>
using IMemory<byte> memory = MMFMemory<byte>.CreateNew(mapName: "name", elementCount: 1000L);
// </01>
for (int ix = 0; ix < memory.Count; ix++) memory[ix] = (byte)ix;
}
{
// <02>
using MemoryMappedFile mmf = MemoryMappedFile.CreateNew("name", 1024L, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.Inheritable);
using IMemory<byte> memory = MMFMemory<byte>.OpenView(mmf);
// </02>
for (int ix = 0; ix < memory.Count; ix++) memory[ix] = (byte)ix;
}
{
// <03>
using IMemory<byte> memory = MMFMemory<byte>.CreateFromFile("file.tmp", FileMode.Create, "name", 1024L);
// </03>
}
unsafe
{
// <09>
long elementCount = 1_000_000;
long byteCount = elementCount * PointerMemory<long>.ByteSizeOfT;
using MemoryMappedFile mmf = MemoryMappedFile.CreateNew(null, byteCount, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.Inheritable);
using MemoryMappedViewAccessor view = mmf.CreateViewAccessor(0, byteCount, MemoryMappedFileAccess.ReadWrite);
byte* ptr = default!;
view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
using MMFMemory<long> memory = new MMFMemory<long>(ptr, byteCount).AttachDisposable(view);
for (long ix = 0L; ix < memory.Count; ix++) memory[ix] = ix;
// </09>
}
{
// <11>
using IMemory<byte> memory =
MMFMemory<byte>.CreateNew(mapName: null, elementCount: 1000L)
.AttachDisposable(() => { });
// </11>
}
{
// <12>
using var memory = MMFMemory<byte>.CreateNew(mapName: null, elementCount: 1000L);
bool a = memory.IsDisposeCalled;
bool b = memory.IsDisposing;
bool c = memory.IsDisposed;
// </12>
}
{
using IMemory<byte> memory = MMFMemory<byte>.CreateNew(mapName: null, elementCount: 1000L);
// <13>
using IDisposable postponeDispose = ((IDisposeBelatable)memory).BelateDispose();
// </13>
}
}
}