原文 C#共享内存类改进版

改进说明及源码实例下载见:http://blog.csdn.net/zzh8845/archive/2008/11/22/3349963.aspx

ShareMem.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;

namespace ShareMemLib
{
    public class ShareMem
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, 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 handle);

[DllImport("kernel32", EntryPoint = "GetLastError")]
        public static extern int GetLastError();

const int ERROR_ALREADY_EXISTS = 183;

const int FILE_MAP_COPY = 0x0001;
        const int FILE_MAP_WRITE = 0x0002;
        const int FILE_MAP_READ = 0x0004;
        const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

const int PAGE_READONLY = 0x02;
        const int PAGE_READWRITE = 0x04;
        const int PAGE_WRITECOPY = 0x08;
        const int PAGE_EXECUTE = 0x10;
        const int PAGE_EXECUTE_READ = 0x20;
        const int PAGE_EXECUTE_READWRITE = 0x40;

const int SEC_COMMIT = 0x8000000;
        const int SEC_IMAGE = 0x1000000;
        const int SEC_NOCACHE = 0x10000000;
        const int SEC_RESERVE = 0x4000000;

const int INVALID_HANDLE_VALUE = -1;

IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;
        IntPtr m_pwDataWrite = IntPtr.Zero;
        IntPtr m_pwDataRead = IntPtr.Zero;
        bool m_bAlreadyExist = false;
        bool m_bInit = false;
        long m_MemSize = 0;
        int m_length = 0;
        int m_count = 0;
        const int infoSize = 50;
        Semaphore semRead;
        Semaphore semWrite;
        Semaphore semWriteLength;
        String m_pathMSGCSV = "Messages.csv";

public ShareMem()
        {
        }
        ~ShareMem()
        {
            Close();
        }

/// 
        /// 初始化共享内存
        /// 
        /// 共享内存名称
        /// 共享内存大小
        /// 
        public int Init(string strName, long lngSize)
        {
            if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
            m_MemSize = lngSize;
            if (strName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);

if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                {
                    m_bAlreadyExist = true;
                    m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, strName);
                }

if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    return 2; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                    {
                        m_bAlreadyExist = true;
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //---------------------------------------
                //创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize);
                m_pwDataWrite = m_pwData;
                m_pwDataRead = (IntPtr)(m_pwData.GetHashCode() + infoSize);
                if (m_pwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    if (m_bAlreadyExist == false)
                    {
                        //初始化
                    }
                }
                //----------------------------------------
            }
            else
            {
                return 1; //参数错误     
            }

SetSemaphore();
            if (m_bAlreadyExist == false)
            {
                WriteLengthAndCount(0, 0);
            }
            return 0;     //创建成功
        }

/// 
        /// 关闭共享内存
        /// 
        public void Close()
        {
            if (m_bInit)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
            }
        }

public bool SetSemaphore()
        {
            try
            {
                semRead = Semaphore.OpenExisting("ReadShareMemory");
                semWrite = Semaphore.OpenExisting("WriteShareMemory");
                semWriteLength = Semaphore.OpenExisting("WriteLengthShareMemory");
            }
            catch (Exception)
            {
                semRead = new Semaphore(0, 1, "ReadShareMemory");
                semWrite = new Semaphore(1, 1, "WriteShareMemory");
                semWriteLength = new Semaphore(1, 1, "WriteLengthShareMemory");
            }
            return true;
        }

/**
        public int ReadLength()
        {
            Byte[] bytData = new Byte[infoSize];
            if (infoSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, 0, infoSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
            m_length = System.Convert.ToInt32(str);
            return 0;     //读成功
        }

public int WriteLength(int length)
        {
            semWriteLength.WaitOne();
            if (infoSize > m_MemSize) return 2; //超出数据区
            String strLength = System.Convert.ToString(length);
            Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLength);
            if (m_bInit)
            {
                Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
            }
            else
            {
                semWriteLength.Release();
                return 1; //共享内存未初始化
            }
            semWriteLength.Release();
            return 0;
        }
        **/

public int ReadLengthAndCount()
        {
            Byte[] bytData = new Byte[infoSize];
            if (infoSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, 0, infoSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
            String[] strs = System.Text.RegularExpressions.Regex.Split(str, "/0");
            m_length = System.Convert.ToInt32(strs[0]);
            m_count = System.Convert.ToInt32(strs[1]);
            return 0;     //读成功
        }

public int WriteLengthAndCount(int length, int count)
        {
            semWriteLength.WaitOne();
            if (infoSize > m_MemSize) return 2; //超出数据区
            String strLengthAndCount = System.Convert.ToString(length) + "/0" + System.Convert.ToString(count);
            Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLengthAndCount);
            if (m_bInit)
            {
                /**
                Byte[] byteZero = new Byte[infoSize];
                for (int i = 0; i < infoSize; i++)
                {
                    byteZero[i] = (Byte)'/0';
                }
                Marshal.Copy(byteZero, 0, m_pwData, infoSize);
                 * **/
                Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
            }
            else
            {
                semWriteLength.Release();
                return 1; //共享内存未初始化
            }
            semWriteLength.Release();
            return 0;
        }

/// 
        /// 读数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Read(ref byte[] bytData)
        {
            ReadLengthAndCount();
            if (m_length > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwDataRead, bytData, 0, m_length);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //读成功
        }

/// 
        /// 写数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Write(byte[] bytData, int lngSize)
        {
            semWrite.WaitOne();
            ReadLengthAndCount();
            if (m_length + lngSize > m_MemSize)
            {
                System.Windows.Forms.MessageBox.Show("Share memory is full. " + (m_length + lngSize) + ">" + m_MemSize);
                semWrite.Release();
                return 2; //超出数据区
            }
            if (m_bInit)
            {
                m_pwDataWrite = (IntPtr)(m_pwData.GetHashCode() + m_length + infoSize);
                Marshal.Copy(bytData, 0, m_pwDataWrite, lngSize);
                m_length += lngSize;
                m_count++;
            }
            else
            {
                semWrite.Release();
                return 1; //共享内存未初始化
            }
            WriteLengthAndCount(m_length, m_count);
            semWrite.Release();
            return 0;     //写成功
        }

public int GetLength()
        {
            ReadLengthAndCount();
            return this.m_length;
        }

public int GetCount()
        {
            ReadLengthAndCount();
            return this.m_count;
        }

public int ReadCSV()
        {
            try
            {
                if (!File.Exists(m_pathMSGCSV))
                    File.CreateText(m_pathMSGCSV).Close();

StreamReader sr = System.IO.File.OpenText(m_pathMSGCSV);
                while (!sr.EndOfStream)
                {
                    String strLine = sr.ReadLine();
                    if (!System.String.IsNullOrEmpty(strLine))
                    {
                        strLine += "/0";
                        Byte[] data = System.Text.Encoding.Unicode.GetBytes(strLine);
                        Write(data, data.Length);
                    }
                }
                sr.Close();
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("Error:ReadCSV()" + e);
                return 1;
            }
            return 0;
        }

public int WriteCSV()
        {
            try
            {
                StreamWriter sw = System.IO.File.AppendText(m_pathMSGCSV);
                ReadLengthAndCount();
                Byte[] btydata = new Byte[m_length];
                Read(ref btydata);
                String strOut = System.Text.Encoding.Unicode.GetString(btydata).Trim('/0');
                String[] sArray = System.Text.RegularExpressions.Regex.Split(strOut, "/0");
                foreach (String str in sArray)
                {
                    if (!String.IsNullOrEmpty(str))
                        sw.WriteLine(str);
                }
                sw.Flush();
                sw.Close();
            }
            catch (Exception)
            {
                System.Windows.Forms.MessageBox.Show("Error:WriteCSV()");
                return 1;
            }
            return 0;
        }

public int Clear()
        {
            ReadLengthAndCount();
            if (infoSize + m_length > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Byte[] byteZero = new Byte[infoSize + m_length];
                for (int i = 0; i < infoSize; i++)
                {
                    byteZero[i] = (Byte)'/0';
                }
                Marshal.Copy(byteZero, 0, m_pwData, infoSize + m_length);
                m_pwDataWrite = m_pwData;
                m_length = 0;
                m_count = 0;
                WriteLengthAndCount(0, 0);
            }
            return 0;
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ShareMemLib;

namespace ShareMemory
{
    public partial class frmMain : Form
    {
        ShareMem MemDB = new ShareMem();
        const int m_memSize = 4096000;

public frmMain()
        {
            InitializeComponent();
            btnInit.Enabled = true;
            btnWrite.Enabled = false;
            btnRead.Enabled = false;
            txtInput.Text = "AAA";
        }

private void ReadTest()
        {
            String str = ReadToStr();
            String[] strArray = System.Text.RegularExpressions.Regex.Split(str, "/0");
            lstData.Items.Clear();
            foreach (String s in strArray)
            {
                lstData.Items.Add(s);
            }
        }

private String ReadToStr()
        {
            int currentLength = MemDB.GetLength();
            int currentCount = MemDB.GetCount();
            Byte[] data = new Byte[currentLength];
            MemDB.Read(ref data);
            lblUsedSize.Text = currentLength.ToString();
            lblCount.Text = currentCount.ToString();
            return System.Text.Encoding.Unicode.GetString(data);
        }

private void WriteStr(String str)
        {
            btnWrite.Enabled = false;
            try
            {
                Byte[] data = System.Text.Encoding.Unicode.GetBytes(str);
                MemDB.Write(data, data.Length);
            }
            catch (Exception)
            {
                MessageBox.Show("Error in WriteStr");
            }
            btnWrite.Enabled = true;
        }

private void btnInit_Click(object sender, EventArgs e)
        {
            if (MemDB.Init("YFMemTest", m_memSize) != 0)
            {
                //初始化失败
                MessageBox.Show("初始化失败");
            }
            else
            {
                btnInit.Enabled = false;
                btnWrite.Enabled = true;
                btnRead.Enabled = true;
            }
            lblTotalSize.Text = m_memSize.ToString();
        }

private void btnClear_Click(object sender, EventArgs e)
        {
            MemDB.Clear();
            ReadTest();
        }

private void btnReadCSV_Click(object sender, EventArgs e)
        {
            MemDB.ReadCSV();
            ReadTest();
        }

private void btnWriteCSV_Click(object sender, EventArgs e)
        {
            MemDB.WriteCSV();
            MemDB.Clear();
            ReadTest();
        }

private void btnRead_Click(object sender, EventArgs e)
        {
            ReadTest();
        }

private void btnWrite_Click(object sender, EventArgs e)
        {
            //String str = "B000" + (i++) + ",1,1,2008,success/0";
            String str = txtInput.Text + System.DateTime.Now.ToString(",yyyMMdd,HHmmss,fff/0");
            WriteStr(str);

ReadTest();
        }
    }
}

C#共享内存类改进版的更多相关文章

  1. C#共享内存实例 附源码

    原文 C#共享内存实例 附源码 网上有C#共享内存类,不过功能太简单了,并且写内存每次都从开头写.故对此进行了改进,并做了个小例子,供需要的人参考. 主要改进点: 通过利用共享内存的一部分空间(以下称 ...

  2. Boost:shared_memory_object --- 共享内存

    什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时, ...

  3. 共享内存操作类(C#源码)

    原文 http://blog.csdn.net/yefanqiu/article/details/1717458 VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由 ...

  4. PHP共享内存yac操作类

    http://www.laruence.com/2013/03/18/2846.html   鸟哥介绍 https://www.cnblogs.com/willamwang/p/8918377.htm ...

  5. php操作共享内存shmop类及简单使用测试(代码)

    SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段.在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码.可以使用 3 ...

  6. 撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)

    一:任务描写叙述 A,B两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递採用共享内存,相应的有一个B1 ...

  7. OpenMP共享内存并行编程详解

    实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...

  8. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

  9. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

随机推荐

  1. VS快捷方式小技巧

    VS2005代码编辑器的展开和折叠代码确实很方便和实用.以下是展开代码和折叠代码所用到的快捷键,很常用: Ctrl + M + O: 折叠所有方法 Ctrl + M + M: 折叠或者展开当前方法 C ...

  2. 8月9日,PS、计算机基础(预科)

    一.   PS         掌握简单的图标修改. 1.图层                 2.保存PSD格式,有图层:JPG格式,没有图层.                 3.魔棒工具(调整值 ...

  3. 玩转kindle paperwhite: 如何越狱,安装强大外挂软件koreader

    NOTICE 1: 在更新kpvbooklet和使用最新版本的koreader(v2013.03-211)时候,会出现pdf文档无法重排的错误.亲测. 如果你是使用的最新版本koreader且出现上述 ...

  4. Java学习之基本数据类型

    基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型.它们是我们编程中使用最频繁的类型.java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变量的初始化. 1. Java ...

  5. hadoop搭建杂记:Linux下虚拟机集群网络搭建

    VirtualBox搭建hadoop伪分布式模式 VirtualBox搭建hadoop伪分布式模式 master: ip:192.168.56.120 机器名: master 启动NameNode 启 ...

  6. Unity 4.2.0 官方最新破解版(Unity3D 最新破解版,3D游戏开发工具和游戏引擎套件)

    Unity是一款跨平台的游戏开发工具,从一开始就被设计成易于使用的产品.作为一个完全集成的专业级应用,Unity还包含了价值数百万美元的功能强大的游戏引擎.Unity作为一个游戏开发工具,它的设计主旨 ...

  7. python cmd命令调用

    关于python调用cmd命令: 主要介绍两种方式: 1.python的OS模块. OS模块调用CMD命令有两种方式:os.popen(),os.system(). 都是用当前进程来调用. os.sy ...

  8. 国产编程语言R++ V1.5发布

    R++ v1.5内核改动较大,下面是一些主要变化: 1.使用PJIT(Pseudocode Just-In-Time),编译速度大幅提高,但运行效率远远不如C++,不过R++将在下一版本支持RJIT( ...

  9. ZOJ 1698 (最大流入门)

    Power NetworkTime Limit:5000MS    Memory Limit:32768KB    64bit IO Format:%lld & %llu SubmitStat ...

  10. HTML DOM访问

    访问 HTML 元素(节点) 访问 HTML 元素等同于访问节点 您能够以不同的方式来访问 HTML 元素: 通过使用 getElementById() 方法 通过使用 getElementsByTa ...