├── README.md ├── .gitignore ├── LICENSE ├── LeslieXin.SimpleMMF.sln ├── LeslieXin.SimpleMMF ├── LeslieXin.SimpleMMF.csproj └── SimpleMMF.cs └── .gitattributes /README.md: -------------------------------------------------------------------------------- 1 | # LeslieXin.SimpleMMF 2 | 3 | #### 介绍 4 | 基于共享内存的、极低CPU和内存占用的、跨进程实时交互类库。 5 | 6 | nuget: https://www.nuget.org/packages/LeslieXin.SimpleMMF 7 | 8 | https://github.com/lesliexinxin/LeslieXin.SimpleMMF 9 | 10 | http://www.lesliexin.com 11 | 12 | https://www.cnblogs.com/lesliexin 13 | 14 | lesliexin@outlook.com 15 | 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows thumbnail cache files 2 | Thumbs.db 3 | Thumbs.db:encryptable 4 | ehthumbs.db 5 | ehthumbs_vista.db 6 | 7 | # Dump file 8 | *.stackdump 9 | 10 | # Folder config file 11 | [Dd]esktop.ini 12 | 13 | # Recycle Bin used on file shares 14 | $RECYCLE.BIN/ 15 | 16 | # Windows Installer files 17 | *.cab 18 | *.msi 19 | *.msix 20 | *.msm 21 | *.msp 22 | 23 | # Windows shortcuts 24 | *.lnk 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 lesliexin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LeslieXin.SimpleMMF.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35327.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LeslieXin.SimpleMMF", "LeslieXin.SimpleMMF\LeslieXin.SimpleMMF.csproj", "{77600F7F-A489-4288-8753-9D9F4EDC84B0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {77600F7F-A489-4288-8753-9D9F4EDC84B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {77600F7F-A489-4288-8753-9D9F4EDC84B0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {77600F7F-A489-4288-8753-9D9F4EDC84B0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {77600F7F-A489-4288-8753-9D9F4EDC84B0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {BFA17EF1-A33F-4A61-85DC-39E16E69F380} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /LeslieXin.SimpleMMF/LeslieXin.SimpleMMF.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | True 6 | D:\Study\Program\C#\LESLIE DLL\LESLIEXIN_UI\LESLIEXIN_UI\LESLIEXIN.pfx 7 | Copyright © LESLIE XIN 2019-2025 8 | True 9 | LeslieXin.SimpleMMF 10 | 1.1.0.0 11 | 1.1.0.0 12 | https://github.com/lesliexinxin/LeslieXin.SimpleMMF 13 | git 14 | 大幅降低CPU和内存占用 15 | 基于共享内存的、极低CPU和内存占用的、跨进程实时交互类库。 16 | d9c299fb-5ce8-4e50-980d-323c12e5d13a 17 | 1.1.0.0 18 | lesliexin 19 | LESLIEXIN SOFTWARE 20 | https://github.com/lesliexinxin/LeslieXin.SimpleMMF 21 | logo_x120.png 22 | ReadMe.md 23 | MIT 24 | True 25 | 26 | 27 | 28 | 29 | True 30 | \ 31 | 32 | 33 | True 34 | \ 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /LeslieXin.SimpleMMF/SimpleMMF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.IO.MemoryMappedFiles; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | namespace LeslieXin.SimpleMMF 9 | { 10 | /* Author: Leslie Xin 11 | * E-Mail: lesliexin@outlook.com 12 | * WebSite: http://www.lesliexin.com 13 | * Datetime: 2021-08-03 06:55:03 14 | * 15 | * V2 16 | */ 17 | 18 | 19 | 20 | /// 21 | /// LeslieXin.SimpleMMF 22 | /// 23 | public class SimpleMMF 24 | { 25 | /// 26 | /// 实例化服务 27 | /// 28 | /// 服务名称 29 | /// 监测规则 30 | /// 事件重置方式,默认:WaitFor 31 | public SimpleMMF(string serverName, MMFRole role, MMFResetRole resetRole = MMFResetRole.WaitFor) 32 | { 33 | Role = role; 34 | ResetRole = resetRole; 35 | ServerName = serverName; 36 | InitWorker(); 37 | } 38 | 39 | 40 | ~SimpleMMF() 41 | { 42 | worker.CancelAsync(); 43 | MMFDispose(); 44 | } 45 | 46 | private string ServerName; 47 | private bool IsBusy; 48 | private MMFRole Role; 49 | private MMFResetRole ResetRole; 50 | /// 51 | /// 监测规则 52 | /// 53 | public enum MMFRole 54 | { 55 | /// 56 | /// Server方 57 | /// 58 | Server, 59 | /// 60 | /// Client方 61 | /// 62 | Client 63 | } 64 | /// 65 | /// 事件重置方式 66 | /// 67 | public enum MMFResetRole 68 | { 69 | /// 70 | /// 事件调用执行后再重置 71 | /// 72 | WaitFor, 73 | /// 74 | /// 事件调用执行前重置 75 | /// 76 | Return 77 | } 78 | 79 | private BackgroundWorker worker; 80 | private static readonly object locker = new object(); 81 | 82 | private EventWaitHandle _eventClient, _eventServer; 83 | 84 | /// 85 | /// 监测规则为Server时,实现此事件,以获取写入的消息 86 | /// 87 | public event EventHandler ServerMsgReceived; 88 | /// 89 | /// 监测规则为Client时,实现此事件,以获取写入的消息 90 | /// 91 | public event EventHandler ClientMsgReceived; 92 | 93 | private void InitWorker() 94 | { 95 | _eventClient = new EventWaitHandle(false, EventResetMode.ManualReset, ServerName + "_Client"); 96 | _eventServer = new EventWaitHandle(false, EventResetMode.ManualReset, ServerName + "_Server"); 97 | 98 | worker = new BackgroundWorker(); 99 | worker.WorkerSupportsCancellation = true; 100 | worker.DoWork += Worker_DoWork; 101 | worker.RunWorkerAsync(); 102 | } 103 | 104 | private void Worker_DoWork(object sender, DoWorkEventArgs e) 105 | { 106 | while (!e.Cancel) 107 | { 108 | if (worker.CancellationPending) 109 | { 110 | e.Cancel = true; 111 | continue; 112 | } 113 | if (IsBusy) continue; 114 | 115 | if (Role == MMFRole.Client) 116 | { 117 | _eventServer.WaitOne(); 118 | string msg = MMFRead(); 119 | if (ResetRole == MMFResetRole.Return) 120 | { 121 | _eventServer.Reset(); 122 | } 123 | ClientMsgReceived?.Invoke(this, msg); 124 | if (ResetRole == MMFResetRole.WaitFor) 125 | { 126 | _eventServer.Reset(); 127 | } 128 | } 129 | 130 | else if (Role == MMFRole.Server) 131 | { 132 | _eventClient.WaitOne(); 133 | string msg = MMFRead(); 134 | if (ResetRole == MMFResetRole.Return) 135 | { 136 | _eventClient.Reset(); 137 | } 138 | ServerMsgReceived?.Invoke(this, msg); 139 | if (ResetRole == MMFResetRole.WaitFor) 140 | { 141 | _eventClient.Reset(); 142 | } 143 | } 144 | 145 | } 146 | } 147 | 148 | /// 149 | /// 向共享内存中写入信息,写入后会自动发送给对方 150 | /// 151 | /// 待写入信息 152 | public void MMFWrite(string msg) 153 | { 154 | IsBusy = true; 155 | long capacity = 1 << 10 << 10 << 10; 156 | var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}", capacity, MemoryMappedFileAccess.ReadWrite); 157 | lock (locker) 158 | { 159 | using (var accessor = mmf.CreateViewAccessor(0, capacity)) 160 | { 161 | accessor.Write(0, msg.Length); 162 | accessor.WriteArray(sizeof(Int32), msg.ToArray(), 0, msg.Length); 163 | } 164 | } 165 | if (Role == MMFRole.Client) 166 | { 167 | _eventClient.Set(); 168 | } 169 | else if (Role == MMFRole.Server) 170 | { 171 | _eventServer.Set(); 172 | } 173 | IsBusy = false; 174 | } 175 | 176 | private string MMFRead() 177 | { 178 | long capacity = 1 << 10 << 10 << 10; 179 | var mmf = MemoryMappedFile.CreateOrOpen($"{ServerName}", capacity, MemoryMappedFileAccess.ReadWrite); 180 | lock (locker) 181 | { 182 | using (var accessor = mmf.CreateViewAccessor(0, capacity)) 183 | { 184 | int strLen = accessor.ReadInt32(0); 185 | char[] chars = new char[strLen]; 186 | accessor.ReadArray(sizeof(Int32), chars, 0, strLen); 187 | return new string(chars); 188 | } 189 | } 190 | } 191 | 192 | private void MMFDispose() 193 | { 194 | try 195 | { 196 | var mmf = MemoryMappedFile.OpenExisting($"{ServerName}"); 197 | mmf.Dispose(); 198 | } 199 | catch (Exception) 200 | { 201 | } 202 | try 203 | { 204 | _eventClient?.Dispose(); 205 | } 206 | catch (Exception) 207 | { 208 | } 209 | try 210 | { 211 | _eventServer?.Dispose(); 212 | } 213 | catch (Exception) 214 | { 215 | } 216 | } 217 | 218 | /// 219 | /// string -> byte[] ,UTF8 220 | /// 221 | /// 222 | /// 223 | /// 224 | public byte[] Convert(string msg,Encoding encoding) 225 | { 226 | return Encoding.UTF8.GetBytes(msg); 227 | } 228 | 229 | /// 230 | /// string -> byte[],UTF8 231 | /// 232 | /// 233 | /// 234 | public string Convert(byte[] msg) 235 | { 236 | return Encoding.UTF8.GetString(msg); 237 | } 238 | } 239 | } 240 | --------------------------------------------------------------------------------