C#共享内存技巧

自己备忘使用

//在共享内存中一定要做好挥斥信号量的使用,防止多个进程同时进行修改内存,可以吧共享内存作为临界资源处理

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace CommonLib
{
    public class SharedMemory
    {
        #region DellImport

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr intPtr, int Msg, int wParam, IntPtr IParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr ipAtttribute, uint flProtect, uint dwMaxSize, uint dwMaxSizeLow, string ipName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesAccess, [MarshalAs(UnmanagedType.Bool)] bool blHeritHanndle, string IpName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesireAccess, uint dwFileOffSetHigh, uint dwFileOffSetLow, uint dwNumberOfbytesToMap);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr hanndle);

        [DllImport("kernel32.dll", EntryPoint = "GetLastError")]
        public static extern int GetLatError();
        #endregion

        #region Const
        const int Error_Alerady_Exists = 183;
        const int File_Map_Write = 0x0002;
        const int File_Map_Read = 0x0004;
        const int File_Map_All_Access = 0x0002 | 0x0004;
        const int Page_Read_Write = 0x04;
        const int Invalib_Handle_value = -1;

        const int Memory_MaxSize = 0x00800000;
        #endregion

        #region Var

        IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;

        bool m_Blint = false;
        long m_Memsize = 0;
        Mutex mutex;

        private string sharedMemoryName = string.Empty;
        public string SharedMemoryName { get { return sharedMemoryName; } }

        public long SharedMemorySize { get { return m_Memsize; } }

        public enum InitResult
        {
            OK,
            Fail,
            ParamError,
        }

        #endregion

        #region  ctor

        public SharedMemory(string moryName)
        {
            sharedMemoryName = moryName;
            if (mutex == null)
            {
                var tempMut = CreateMutexOrOpen(moryName);
                if (tempMut == null)
                {
                    throw new Exception("Mutex is null");
                }
                else
                {
                    mutex = tempMut;
                }
            }
        }

        /// 
        /// 根据名称创建一个互斥资源
        /// 
        /// 互斥资源名称
        /// 
        private Mutex CreateMutexOrOpen(string moryName)
        {
            string mutName = moryName + "_Mutext";
            Mutex tex = null;
            try
            {
                tex = Mutex.OpenExisting(mutName);
            }
            catch { }
            if (tex is null)
            {
                tex = new Mutex(false, mutName, out bool retBool);
            }
            return tex;
        }

        //析构函数在释放资源时候 调用
        ~SharedMemory()
        {
            Close();
        }
        #endregion


        public InitResult Init(long memorySize)
        {
            mutex.WaitOne();
            try
            {
                if (m_Blint)
                {
                    return InitResult.OK;
                }
                if (string.IsNullOrEmpty(sharedMemoryName))
                {
                    return InitResult.ParamError;
                }
                if (memorySize <= 0 || memorySize > Memory_MaxSize)
                {
                    memorySize = Memory_MaxSize;
                }

                m_Memsize = memorySize;
                //1. 创建内存共享体,存进字段
                m_hSharedMemoryFile = CreateFileMapping(Invalib_Handle_value, IntPtr.Zero, (uint)Page_Read_Write, 0, (uint)memorySize, sharedMemoryName);
                //2. 判断创建内存共享体是否成功
                if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_Blint = false;
                    return InitResult.Fail;
                }
                else
                {
                    if (GetLatError() == Error_Alerady_Exists) //判断内存映射是否已经创建
                    {
                        m_Blint = true;
                    }
                }
                //3. 创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, File_Map_Write, 0, 0, (uint)memorySize);
                //4. 判断内存映射是否成功
                if (m_pwData == IntPtr.Zero)
                {
                    m_Blint = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return InitResult.Fail;
                }
                else
                {
                    m_Blint = true;
                    return InitResult.OK;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                mutex.ReleaseMutex();
            }
        }

        public void Close()
        {
            mutex.WaitOne();
            if (m_Blint)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
            }
            mutex.ReleaseMutex();
            mutex.Close();
        }

        public bool Read(ref byte[] byteData, int lngAddr, int lngSize)
        {
            if (lngAddr + lngSize > m_Memsize | m_pwData == IntPtr.Zero)
            {
                return false;
            }
            if (m_Blint)
            {
                mutex.WaitOne();
                Marshal.Copy(m_pwData, byteData, lngAddr, lngSize);
                mutex.ReleaseMutex();
            }
            else
            {
                return false;
            }
            return true;
        }

        /// 
        /// 写入共享内存
        /// 
        /// 待写入的数据
        /// 待写入数组的位置
        /// 待写入数据长度
        /// 偏移位置
        /// 
        public bool Write(byte[] byteData, int lngAddr, int lngSize, int Offset)
        {
            if (lngAddr + lngSize > m_Memsize)
            {
                return false;
            }
            if (m_Blint)
            {
                mutex.WaitOne();
                Marshal.Copy(byteData, lngAddr, (IntPtr)(m_pwData.ToInt32() + Offset), lngSize);
                mutex.ReleaseMutex();
            }
            else
            {
                return false;
            }
            return true;
        }

        public bool Clear()
        {
            byte[] bts = new byte[m_Memsize];
            return Write(bts, 0, bts.Length, 0);
        }
    }
}

你可能感兴趣的:(默认,c#,操作系统)