c#中不同进程内存共享

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

共享内存今日在项目中碰到一个问题,就是一个程序的两个进程之间需要频繁的传送数据,具体的来说是一个需要频繁的发送数据而另一个实例需要频繁的访问获得这些数据。当然,这个问题是有很多解的,例如:数据库,再例如:文件。可是因为这个频繁程度太高了,例如:一秒钟十次,在这种情况下,使用数据库或者是文件可能都不是一个GoodIdea。Update:其实开始想到的方案还包括Remoting,Socket之类的,不过明显的是小题大做,杀鸡用牛刀了,呵呵。所以最后也就放弃了。那么什么解决方案好呢?众所周知,内存的速度是除了CPU缓存外最快的,当然是我们的首选了,可是看遍了.Net的类库也没有找到可以用来实现这个方案的办法,看来只能依靠Win32API了。在网上得到资料,可以使用API开辟共享内存从而达到在不同的进程之间共享数据的可能。关键API类:viewsourceprint?publicstaticclassAPI{[DllImport(user32.dll,CharSet=CharSet.Auto)]publicstaticexternIntPtrSendMessage(IntPtrhWnd,intMsg,intwParam,IntPtrlParam);[DllImport(Kernel32.dll,CharSet=CharSet.Auto)]publicstaticexternIntPtrCreateFileMapping(inthFile,IntPtrlpAttributes,uintflProtect,uintdwMaxSizeHi,uintdwMaxSizeLow,stringlpName);[DllImport(Kernel32.dll,CharSet=CharSet.Auto)]publicstaticexternIntPtrOpenFileMapping(intdwDesiredAccess,[MarshalAs(UnmanagedType.Bool)]boolbInheritHandle,stringlpName);[DllImport(Kernel32.dll,CharSet=CharSet.Auto)]publicstaticexternIntPtrMapViewOfFile(IntPtrhFileMapping,uintdwDesiredAccess,uintdwFileOffsetHigh,uintdwFileOffsetLow,uintdwNumberOfBytesToMap);[DllImport(Kernel32.dll,CharSet=CharSet.Auto)]publicstaticexternboolUnmapViewOfFile(IntPtrpvBaseAddress);[DllImport(Kernel32.dll,CharSet=CharSet.Auto)]publicstaticexternboolCloseHandle(IntPtrhandle);[DllImport(kernel32,EntryPoint=GetLastError)]publicstaticexternintGetLastError();[DllImport(msvcrt.dll,SetLastError=true)]publicstaticexternintmemcmp(IntPtrptr1,IntPtrptr2,intcount);[DllImport(msvcrt.dll,SetLastError=true)]publicstaticexternunsafeintmemcmp(void*ptr1,void*ptr2,intcount);[DllImport(ntdll.dll)]publicstaticexternintRtlCompareMemory(IntPtrDestination,IntPtrSource,intLength);publicconstintERROR_ALREADY_EXISTS=183;publicconstintFILE_MAP_COPY=0x0001;publicconstintFILE_MAP_WRITE=0x0002;publicconstintFILE_MAP_READ=0x0004;publicconstintFILE_MAP_ALL_ACCESS=0x0002|0x0004;publicconstintPAGE_READONLY=0x02;publicconstintPAGE_READWRITE=0x04;publicconstintPAGE_WRITECOPY=0x08;publicconstintPAGE_EXECUTE=0x10;publicconstintPAGE_EXECUTE_READ=0x20;publicconstintPAGE_EXECUTE_READWRITE=0x40;publicconstintSEC_COMMIT=0x8000000;publicconstintSEC_IMAGE=0x1000000;publicconstintSEC_NOCACHE=0x10000000;publicconstintSEC_RESERVE=0x4000000;publicconstintINVALID_HANDLE_VALUE=-1;}代码实现:viewsourceprint?publicenumMemoryResult{Success,NotInitialized,NoChange,Failed}publicclassShareMemoryT:IDisposablewhereT:class{IntPtrm_hSharedMemoryFile=IntPtr.Zero;IntPtrm_pwData=IntPtr.Zero;boolm_bAlreadyExist=false;boolm_bInit=false;longm_MemSize=0;intm_size;byte[]m_lastData;publicShareMemory(){}~ShareMemory(){Close();}///summary///初始化共享内存////summarypublicMemoryResultInit(stringstrName){m_size=10240;//固定10KvarlngSize=m_size;if(lngSize=0||lngSize0x00800000)lngSize=0x00800000;m_MemSize=lngSize;if(strName.Length0){//创建内存共享体(INVALID_HANDLE_VALUE)m_hSharedMemoryFile=API.CreateFileMapping(API.INVALID_HANDLE_VALUE,IntPtr.Zero,(uint)API.PAGE_READWRITE,0,(uint)lngSize,strName);if(m_hSharedMemoryFile==IntPtr.Zero){m_bAlreadyExist=false;m_bInit=false;returnMemoryResult.Failed;//创建共享体失败}else{if(API.GetLastError()==API.ERROR_ALREADY_EXISTS)//已经创建{m_bAlreadyExist=true;}else//新创建{m_bAlreadyExist=false;}}//---------------------------------------//创建内存映射m_pwData=API.MapViewOfFile(m_hSharedMemoryFile,API.FILE_MAP_WRITE,0,0,(uint)lngSize);if(m_pwData==IntPtr.Zero){m_bInit=false;API.CloseHandle(m_hSharedMemoryFile);returnMemoryResult.Failed;//创建内存映射失败}else{m_bInit=true;if(m_bAlreadyExist==false){//初始化}}//----------------------------------------}else{returnMemoryResult.Failed;//参数错误}returnMemoryResult.Success;//创建成功}///summary///关闭共享内存////summarypublicvoidClose(){if(m_bInit){API.UnmapViewOfFile(m_pwData);API.CloseHandle(m_hSharedMemoryFile);}}///summary///读数据////summarypublicunsafeMemoryResultRead(outTobj){obj=default(T);byte[]bytData=newbyte[m_size];if(m_bInit){Marshal.Copy(m_pwData,bytData,0,m_size);if(m_lastData!=null){fixed(byte*p1=m_lastData){fixed(byte*p2=bytData){if(API.memcmp(p1,p2,m_size)==0)returnMemoryResult.NoChange;}}}m_lastData=bytData;varfmt=newBinaryFormatter();using(varms=newMemoryStream(bytData)){try{obj=(T)fmt.Deserialize(ms);}catch(SerializationException){returnMemoryResult.Failed;}}}else{returnMemoryResult.NotInitialized;//共享内存未初始化}returnMemoryResult.Success;//读成功}///summary///写数据////summarypublicMemoryResultWrite(Tobj){varfmt=newBinaryFormatter();byte[]bytData;if(objisbyte[])bytData=objasbyte[];else{using(varms=newMemoryStream()){fmt.Serialize(ms,obj);bytData=ms.ToArray();}}if(m_bInit)Marshal.Copy(bytData,0,m_pwData,bytData.Length);elsereturnMemoryResult.NotInitialized;//共享内存未初始化returnMemoryResult.Success;//写成功}#regionIDisposableMemberspublicvoidDispose(){Close();}#endregion}使用也很简单:viewsourceprint?写数据:if(mem==null){mem=newShareMemoryChannelStatus[]();mem.Init(ChannelStatus);}varxml=PhoneCallHelper.SendRequest(PhoneCallAction.getChStatus);foreach(XmlElementeleinxml.DocumentElement.SelectNodes(chStatus)){varstatus=GetChannelStatusFromXElement(e

1 / 11
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功