首页 > 系统相关 >内存映射MMF

内存映射MMF

时间:2022-11-16 10:46:33浏览次数:37  
标签:string 映射 MMFType private client 内存 msg MMF 服务端

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Text;

namespace Common.MMF
{
    
    public class MMFHelper
    {
        /// <summary>
        /// 作为服务端实例化(instantize as a server)
        /// </summary>
        /// <param name="serverName">服务端名称(server name)<para>需要与客户端的服务端名称保持一致(need to be consistent with the client's server name)</para></param>
        public MMFHelper(string serverName)
        {
            Role = MMFRole.Server;
            ServerName = serverName;
            ClientName = "";
            InitWorker();
        }

        /// <summary>
        /// 作为客户端实例化(instantize as a client)
        /// </summary>
        /// <param name="serverName">服务端名称(server name)<para>需要与服务端的服务端名称保持一致(need to be consistent with the server name on the service side)</para></param>
        /// <param name="clientName">客户端名称(client name)</param>
        public MMFHelper(string serverName, string clientName)
        {
            Role = MMFRole.Client;
            ServerName = serverName;
            ClientName = clientName;
            InitWorker();
        }

        ~SimpleMMF()
        {
            worker.CancelAsync();
            MMFDispose();
        }

        private string ServerName;
        private string ClientName;
        private bool IsBusy;
        private MMFRole Role;
        private enum MMFRole { Server,Client}
        private enum MMFType { STATE,VALUE,CLIENT}
        private BackgroundWorker worker;
        private static readonly object locker = new object();

        /// <summary>
        /// 作为服务端启动时响应此事件(respond to this event when started as a server)<para>参数e为客户端写入的信息(argument e is the information written by the client)</para><para>key:客户端名称(key: client name)</para><para>value:客户端写入信息(key: the information written by the client)</para>
        /// </summary>
        public event EventHandler<KeyValuePair<string, string>> ServerMsg;
        /// <summary>
        /// 作为客户端启动时响应此事件(respond to this event when started as a client)<para>参数e为服务端写入的信息(argument e is the information written by the server)</para><para>key:客户端名称(key: client name)</para><para>value:服务端写入信息(key: the information written by the server)</para>
        /// </summary>
        public event EventHandler<KeyValuePair<string, string>> ClientMsg;

        private void InitWorker()
        {
            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += Worker_DoWork;
            worker.RunWorkerAsync();
        }

        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (!e.Cancel)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    continue;
                }
                if (IsBusy) continue;

                string state = MMFRead(MMFType.STATE);
                if (string.IsNullOrEmpty(state)) continue;
                if (state == "1")
                {
                    //内容发生一次改变则只会触发一次事件,之后状态就复原,不能一直去触发。
                    MMFWrite(MMFType.STATE, "0");
                    if (Role == MMFRole.Client)
                    {
                        string msg = MMFRead(MMFType.VALUE);
                        string client = MMFRead(MMFType.CLIENT);
                        ClientMsg?.Invoke(this, new KeyValuePair<string, string>(client, msg));
                    }
                    continue;
                }
                if (state == "2")
                {
                    //内容发生一次改变则只会触发一次事件,之后状态就复原,不能一直去触发。
                    MMFWrite(MMFType.STATE, "0");
                    if (Role == MMFRole.Server)
                    {
                        string msg = MMFRead(MMFType.VALUE);
                        string client = MMFRead(MMFType.CLIENT);
                        ServerMsg?.Invoke(this, new KeyValuePair<string, string>(client, msg));
                    }
                    continue;
                }
            }
        }

        /// <summary>
        /// 向共享内存中写入信息(write information to shared memory)
        /// </summary>
        /// <param name="msg">待写入信息(the information to be written)</param>
        public void MMFWrite(string msg)
        {
            IsBusy = true;
            MMFWrite(MMFType.VALUE, msg);
            MMFWrite(MMFType.STATE, Role == MMFRole.Server ? "1" : "2");
            if (Role == MMFRole.Client)
                MMFWrite(MMFType.CLIENT, ClientName);
            IsBusy = false;
        }

        private void MMFWrite(MMFType type, string msg)
        {
            long capacity = 1 << 10 << 10 << 10;
            var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}{type.ToString()}", capacity, MemoryMappedFileAccess.ReadWrite);
            lock (locker)
            {
                using (var accessor = mmf.CreateViewAccessor(0, capacity))  //视图
                {
                    accessor.Write(0, msg.Length);
                    accessor.WriteArray<char>(sizeof(Int32), msg.ToArray(), 0, msg.Length);
                }
            }
        }

        private string MMFRead(MMFType type)
        {
            long capacity = 1 << 10 << 10 << 10;
            var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}{type.ToString()}", capacity, MemoryMappedFileAccess.ReadWrite);
            lock (locker)
            {
                using (var accessor = mmf.CreateViewAccessor(0, capacity))
                {
                    int strLen = accessor.ReadInt32(0);
                    char[] chars = new char[strLen];
                    accessor.ReadArray<char>(sizeof(Int32), chars, 0, strLen);
                    return new string(chars);
                }
            }
        }

        private void MMFDispose()
        {
            try
            {
                var mmf = MemoryMappedFile.OpenExisting($"{ServerName}STATE");
                mmf.Dispose();
            }
            catch (Exception)
            {
            }
            try
            {
                var mmf = MemoryMappedFile.OpenExisting($"{ServerName}VALUE");
                mmf.Dispose();
            }
            catch (Exception)
            {
            }
            try
            {
                var mmf = MemoryMappedFile.OpenExisting($"{ServerName}CLIENT");
                mmf.Dispose();
            }
            catch (Exception)
            {
            }
        }

    }
}

 

标签:string,映射,MMFType,private,client,内存,msg,MMF,服务端
From: https://www.cnblogs.com/chase-zhou/p/16895060.html

相关文章

  • JVM堆内存分析,分析工具jmap heap
    一、查看堆信息jmap-heap33146Debuggerattachedsuccessfully.Servercompilerdetected.JVMversionis25.251-b08usingthread-localobjectallocation.Garb......
  • new 在堆内存中开辟内存空间,delete 释放开辟的内存空间
    intmain(){int*p=newint(10);cout<<*p<<endl;deletep;cout<<*p<<endl;int*arr=newint[10];......
  • C++ 内存分区模型
    代码区:存放函数的二进制代码,由操作系统管理全局区:存放全局变量、静态变量以及常量。栈区:由编译器自动分配释放,存放函数的参数值,局部变量等堆区:由程序员分配和释放,若......
  • Java 内存模型及若干相关问题
    java的内存模型的理解java的内存模型是一种抽象,对java语言在不同硬件平台上运行的差异的一种抽象描述,目的是屏蔽不同硬件平台之间的差异。JMM定义了线程和主存之间的访......
  • 【ES】ES内存占用高,扩内存,重启服务注意事项
    一、参考资料​​Elasticsearch内存占用分析与管理|Tink'sBlog​​​​ElasticsearchJVM堆内存使用率飙升,怎么办?-腾讯云开发者社区-腾讯云​​​​ES集群重启注意事......
  • 如何写成高性能的代码(三):巧用稀疏矩阵节省内存占用
    稀疏矩阵的概念一个m×n的矩阵是一个由m行n列元素排列成的矩形阵列。矩阵里的元素可以是数字、符号及其他的类型的元素。一般来说,在矩阵中,若数值为0的元素数目远远多于非0元......
  • 内存分析及数组的3种初始化
    内存分析Java内存分析:数组的3种初始化静态初始化int[]a={1,2,3};Man[]mans={newMan(1,1),newMan(2,2)};动态初始化int[]a=newint[2];a[0]......
  • 为什么要求内存对齐
    当我们在我们的代码中申明变量时,我们通常是不用考虑也不会去做所谓的内存对齐的,因为这个工作本身是属于编译器去完成的。那我们的变量为什么不按照大小顺序地存放而是非要......
  • C++类的内存结构
     第一种这个类是个空类 sizeof会占用一个字节 newt也是占用一个字节但作为其他类的成员变量可能会占用1-2-4-8字节这个是类的内存对齐导致 第2种这......
  • 分页内存与非分页内存的疑惑
    参考:https://bbs.pediy.com/thread-160200.htm张帆《驱动详解》中讲到:当程序的中断请求级在DISPATCH_LEVEL之上时(包括DISPATCH_LEVEL层),程序只能使用非分页内存,否则将......