用于管理共享内存的 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 上直接使用名称
            }
        }
    }
}
相关推荐
一心赚狗粮的宇叔10 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
cplmlm11 小时前
EF Core使用CodeFirst生成postgresql数据库表名以及字段名用蛇形命名法,而类名仍使用驼峰命名
c#
lingxiao1688813 小时前
WebApi详解+Unity注入--下篇:Unity注入
unity·c#·wpf
lingxiao1688815 小时前
WebApi详解+Unity注入--中篇:.net core的WebAPI
unity·c#·.netcore
ServBay16 小时前
C# 成为 2025 年的编程语言,7个C#技巧助力开发效率
后端·c#·.net
故事不长丨19 小时前
C#进制转换:从基础原理到实战应用
开发语言·c#·进制转换·16进制·2进制·10进制
liulilittle19 小时前
VEthernet 框架实现 tun2socks 的技术原理
网络·windows·c#·信息与通信·通信
云草桑20 小时前
.net AI API应用 客户发的信息提取对接上下游系统报价
ai·c#·.net·semantickernel·sk
故事不长丨21 小时前
C#File文件操作全解析:从基础用法到异常处理
服务器·开发语言·visualstudio·c#·文件操作·io流·file
工程师0071 天前
C# 动态编程(基于 dynamic 类型)
开发语言·c#·dynamic·动态编程