用于管理共享内存的 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 上直接使用名称
            }
        }
    }
}
相关推荐
datalover3 小时前
【无标题】
c#·linq
FlYFlOWERANDLEAF4 小时前
微软CommunityToolkit.Mvvm和DevExpress中GenerateViewModel使用
c#
Xin_ye100865 小时前
第七章:进阶篇——事件监听、外部服务集成与性能优化
c#
z落落6 小时前
C# WinForm NModbus 串口通信+WinForm Modbus4 串口通信
开发语言·单片机·c#
CoderIsArt6 小时前
C#环境中部署MQTT客户端
开发语言·c#
CSDN_RTKLIB7 小时前
模型空间、布局控件、自定义块
c#
z落落7 小时前
C# WinForm TCP 服务器+WinForm TCP 客户端
服务器·tcp/ip·c#
csdn_aspnet7 小时前
C# 多个串口多个线程发送数据和接收数据
c#·串口·thread·com·serialport
吴可可12320 小时前
多段线局部约束缩放实现
c#
棉晗榜1 天前
C# HttpClient配置具有tls指纹发起跟浏览器一样的请求解决反爬虫防护
开发语言·爬虫·c#