/// <summary> /// Writes the given <see cref="byte[]"/> data into a <see cref="SharedMemoryMap"/>. /// Note: /// Tracks the reference to the <see cref="SharedMemoryMap"/> after creating it and does not close it. /// </summary> /// <param name="content">Content to write into shared memory.</param> /// <returns>Metadata of the shared memory map into which data is written if successful, <see cref="null"/> otherwise.</returns> private async Task <SharedMemoryMetadata> PutBytesAsync(byte[] content) { // Generate name of shared memory map to write content into string mapName = Guid.NewGuid().ToString(); // Create shared memory map which can hold the content long contentSize = content.Length; SharedMemoryMap sharedMemoryMap = Create(mapName, contentSize); // Ensure the shared memory map was created if (sharedMemoryMap == null) { _logger.LogError("Cannot write content into shared memory"); return(null); } // Write content into shared memory map long bytesWritten = await sharedMemoryMap.PutBytesAsync(content); // Ensure that the entire content has been written into the shared memory map if (bytesWritten != contentSize) { _logger.LogError("Cannot write complete content into shared memory map: {MapName}; wrote: {BytesWritten} bytes out of total: {ContentSize} bytes", mapName, bytesWritten, contentSize); return(null); } // Track the shared memory map (to keep a reference open so that the OS does not free the memory) if (!AllocatedSharedMemoryMaps.TryAdd(mapName, sharedMemoryMap)) { _logger.LogError("Cannot add shared memory map: {MapName} to list of allocated maps", mapName); sharedMemoryMap.Dispose(); return(null); } // Respond back with metadata about the created and written shared memory map SharedMemoryMetadata response = new SharedMemoryMetadata { Name = mapName, Count = contentSize }; return(response); }
/// <summary> /// Reads data as <see cref="byte[]"/> from the <see cref="SharedMemoryMap"/> with the given name. /// </summary> /// <param name="mapName">Name of the <see cref="MemoryMappedFile"/> to read from.</param> /// <param name="offset">Offset to start reading data from in the <see cref="SharedMemoryMap"/>.</param> /// <param name="count">Number of bytes to read from, starting from the offset, in the <see cref="SharedMemoryMap"/>.</param> /// <returns>Data read as <see cref="byte[]"/> if successful, <see cref="null"/> otherwise. /// </returns> private async Task <byte[]> GetBytesAsync(string mapName, int offset, int count) { SharedMemoryMap sharedMemoryMap = Open(mapName); try { byte[] content = await sharedMemoryMap.GetBytesAsync(offset, count); if (content == null) { _logger.LogError($"Cannot read content from MemoryMappedFile: {mapName}"); throw new Exception($"Cannot read content from MemoryMappedFile: {mapName} with offset: {offset} and count: {count}"); } return(content); } finally { sharedMemoryMap.Dispose(deleteFile: false); } }