├── 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 |
--------------------------------------------------------------------------------