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

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

代码分析

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

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

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

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

    • _isInitialized_isOpened 标志用于跟踪共享内存的状态。
cs 复制代码
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 上直接使用名称
            }
        }
    }
}
相关推荐
聪明努力的积极向上14 分钟前
【C#】HTTP中URL编码方式解析
开发语言·http·c#
关关长语3 小时前
(四) Dotnet中MCP客户端与服务端交互通知日志信息
ai·c#·mcp
小码编匠3 小时前
WPF 动态模拟CPU 使用率曲线图
后端·c#·.net
聪明努力的积极向上3 小时前
【.NET】依赖注入浅显解释
c#·.net
hixiong1234 小时前
C# OpencvSharp使用lpd_yunet进行车牌检测
开发语言·opencv·计算机视觉·c#
专注VB编程开发20年6 小时前
.net c#音频放大,音量增益算法防止溢出
算法·c#·音频处理·录音·音量增益·增益控制
专注VB编程开发20年6 小时前
.NET Reflector反编绎,如何移除DLL中的一个公开属性
开发语言·c++·c#
唐青枫9 小时前
C#.NET Random 深入解析:随机数生成原理与最佳实践
c#·.net
永远有缘10 小时前
Java、Python、C# 和 C++ 在函数定义语法上的主要区别
java·c++·python·c#
yue00816 小时前
C#理论学习-WinForm实践开发教程总结
开发语言·学习·c#