Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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);
            }
        }