用于管理共享内存的 C# 类 ShareMemory

发布于:2025-05-22 ⋅ 阅读:(14) ⋅ 点赞:(0)

可以在 Windows 和 Linux 上运行,利用了 .NET Core 的 System.IO.MemoryMappedFiles 库。这个类实现了共享内存的创建、打开、读取和写入功能。以下是对代码的一些分析和建议改进。

代码分析

  1. 初始化与打开共享内存:

    • Init 方法用于创建新的共享内存段。
    • OpenMem 方法用于打开已存在的共享内存段。
    • 这两个方法都处理了异常并返回状态码,非常适合用于错误处理。
  2. 关闭共享内存:

    • Close 方法确保释放资源,避免内存泄漏。
  3. 读写数据:

    • Read 和 Write 方法提供了数据读写的功能,支持指定偏移量和大小。
  4. 状态管理:

    • _isInitialized 和 _isOpened 标志用于跟踪共享内存的状态。
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;

namespace MemoryDB
{
    class Class_ShareMemory
    {
        private MemoryMappedFile _memoryMappedFile;
        private MemoryMappedViewAccessor _viewAccessor;
        private long _memSize;
        private string _name;
        private bool _isInitialized;
        private bool _isOpened;

        public Class_ShareMem()
        {
            _isInitialized = false;
            _isOpened = false;
        }

        /// <summary>
        /// 初始化共享内存
        /// </summary>
        /// <param name="name">共享内存名称</param>
        /// <param name="size">共享内存大小</param>
        /// <returns></returns>
        public int Init(string name, long size)
        {
            if (size <= 0) size = 0x00800000; // Default size
            _memSize = size;
            _name = name;

            try
            {
                // 根据操作系统设置共享内存名称
                string fullName = GetFullMemoryMappedFileName(_name);
                _memoryMappedFile = MemoryMappedFile.CreateNew(fullName, _memSize);
                _viewAccessor = _memoryMappedFile.CreateViewAccessor();
                _isInitialized = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"创建共享内存失败: {ex.Message}");
                return 2; // 创建失败
            }

            return 0; // 创建成功
        }

        /// <summary>
        /// 打开共享内存
        /// </summary>
        public int OpenMem(string name, long size)
        {
            if (size <= 0) size = 0x00800000; // Default size
            _memSize = size;
            _name = name;

            try
            {
                // 根据操作系统设置共享内存名称
                string fullName = GetFullMemoryMappedFileName(_name);
                _memoryMappedFile = MemoryMappedFile.OpenExisting(fullName);
                _viewAccessor = _memoryMappedFile.CreateViewAccessor();
                _isOpened = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"打开共享内存失败: {ex.Message}");
                return 1; // 打开失败
            }

            return 0; // 打开成功
        }

        /// <summary>
        /// 关闭共享内存
        /// </summary>
        public void Close()
        {
            _viewAccessor?.Dispose();
            _memoryMappedFile?.Dispose();
            _isInitialized = false;
            _isOpened = false;
        }

        /// <summary>
        /// 读数据
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="offset">起始地址</param>
        /// <param name="size">个数</param>
        /// <returns></returns>
        public int Read(ref byte[] data, long offset, int size)
        {
            if (offset + size > _memSize) return 2; // 超出数据区
            if (_isInitialized || _isOpened)
            {
                _viewAccessor.ReadArray(offset, data, 0, size);
            }
            else
            {
                return 1; // 共享内存未初始化
            }

            return 0; // 读成功
        }

        /// <summary>
        /// 写数据
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="offset">起始地址</param>
        /// <param name="size">个数</param>
        /// <returns></returns>
        public int Write(byte[] data, long offset, int size)
        {
            if (offset + size > _memSize) return 2; // 超出数据区
            if (_isInitialized || _isOpened)
            {
                _viewAccessor.WriteArray(offset, data, 0, size);
            }
            else
            {
                return 1; // 共享内存未初始化
            }

            return 0; // 写成功
        }

        /// <summary>
        /// 根据操作系统获取完整的共享内存名称
        /// </summary>
        /// <param name="name">共享内存名称</param>
        /// <returns>完整的共享内存名称</returns>
        private string GetFullMemoryMappedFileName(string name)
        {
            // 在 Windows 中使用 Global 前缀,在 Linux 中不使用
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return $"Global\\{name}";
            }
            else
            {
                return name; // Linux 上直接使用名称
            }
        }
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到