一、共享内存的帮助类
/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描 述:两个exe程序之间通信_共享内存传递(基础示例,程序中使用时不进一步封装是不够的)
*│ 作 者:执笔小白
*│ 版 本:1.0
*│ 创建时间:2022-12-06 10:40:56
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 命名空间: Communication_Between_exe_ProgramsHelper
*│ 类 名:Communication_SharedMemoryHelper
*└──────────────────────────────────────────────────────────────┘
*/
using Newtonsoft.Json;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
namespace Communication_Between_exe_ProgramsHelper
{
/// <summary>
/// 两个exe程序之间通信_共享内存传递(主从运行,不可单独运行)
/// </summary>
public class Communication_SharedMemoryHelper
{
/*
* 二进制 100=0x1100100
*
* 注意一:线程或进程间通讯时使用互斥锁
* //bool mutexCreated;
* //Mutex mutex = newMutex(true, "testmapmutex", out mutexCreated); // 创建锁(指定锁名)
* //try{
* // mutex.WaitOne(); // 等待其他程序释放锁
* // // 通讯处理...
* //}
* //finally{
* // mutex.ReleaseMutex(); // 释放锁
* //}
*
* 注意二:非持久文件映射时,注意MemoryMappedFile不要被GC。
*
*/
#region 非持久文件映射
/*
* 1、非持久文件映射
* 非持久文件是未与磁盘上的源文件关联的内存映射文件。
* 当最后一个进程使用完此文件后,数据将丢失,并且垃圾回收功能将回收此文件。
* 可使用非托管对象防止被回收
*/
private static MemoryMappedFile? mmf_NoKeep;
/// <summary>
/// 内存共享_基于流的操作_读-非持久文件映射
/// </summary>
/// <param name="mmfName">共享内容对象名</param>
/// <returns></returns>
public static MemoryMappedFile_ShareInfo_ViewStream MemoryMappedFile_ViewStream_Read_NoKeep(string mmfName)
{
MemoryMappedFile_ShareInfo_ViewStream resultShareInfo = new();
mmf_NoKeep = MemoryMappedFile.CreateOrOpen(mmfName, 0x1100100, MemoryMappedFileAccess.ReadWrite); // 打开共享内存区域,大小默认为100MB
using (MemoryMappedViewStream stream = mmf_NoKeep.CreateViewStream())
{
if (stream.CanRead)
{
BinaryReader reader = new(stream);
if (JsonConvert.DeserializeObject<MemoryMappedFile_ShareInfo_ViewStream>(reader.ReadString()) is MemoryMappedFile_ShareInfo_ViewStream share)
{
resultShareInfo = share;
}
}
}
return resultShareInfo;
}
/// <summary>
/// 内存共享_基于内存偏移量的操作_读-非持久文件映射
/// </summary>
/// <param name="mmfName">共享内容对象名</param>
/// <returns></returns>
public static MemoryMappedFile_ShareInfo_ViewAccessor MemoryMappedFile_ViewAccessor_Read_NoKeep(string mmfName)
{
MemoryMappedFile_ShareInfo_ViewAccessor resultShareInfo = new();
mmf_NoKeep = MemoryMappedFile.CreateOrOpen(mmfName, 0x1100100, MemoryMappedFileAccess.ReadWrite); // 打开共享内存区域,大小默认为100MB
using (MemoryMappedViewAccessor accessor = mmf_NoKeep.CreateViewAccessor(0, 100)) // 注意这里的偏移量,大小;大小100MB
{
int colorSize = Marshal.SizeOf(typeof(MemoryMappedFile_ShareInfo_ViewAccessor));
accessor.Read(0, out resultShareInfo); // 读取视图
}
return resultShareInfo;
}
/// <summary>
/// 内存共享_基于流的操作_写-非持久文件映射
/// </summary>
/// <param name="mmfName">共享内容对象名</param>
/// <param name="share">写入的内容</param>
public static bool MemoryMappedFile_ViewStream_Wirte_NoKeep(string mmfName, MemoryMappedFile_ShareInfo_ViewStream shareInfo)
{
bool result = false;
mmf_NoKeep = MemoryMappedFile.CreateOrOpen(mmfName, 0x1100100, MemoryMappedFileAccess.ReadWrite); // 打开共享内存区域,大小默认为100MB
using (MemoryMappedViewStream stream = mmf_NoKeep.CreateViewStream())
{
result = stream.CanWrite;
if (result)
{
BinaryWriter writer = new(stream);
writer.Write(JsonConvert.SerializeObject(shareInfo));
}
}
return result;
}
/// <summary>
/// 内存共享_基于内存偏移量的操作_写-非持久文件映射
/// </summary>
/// <param name="mmfName"></param>
/// <param name="shareInfo"></param>
/// <returns></returns>
public static bool MemoryMappedFile_ViewAccessor_Wirte_NoKeep(string mmfName, MemoryMappedFile_ShareInfo_ViewAccessor shareInfo)
{
bool result = false;
mmf_NoKeep = MemoryMappedFile.CreateOrOpen(mmfName, 0x1100100, MemoryMappedFileAccess.ReadWrite); // 打开共享内存区域,大小默认为100MB
using (MemoryMappedViewAccessor accessor = mmf_NoKeep.CreateViewAccessor(0, 100)) // 注意这里的偏移量,大小;大小100MB
{
result = accessor.CanRead;
if (result)
{
int colorSize = Marshal.SizeOf(typeof(MemoryMappedFile_ShareInfo_ViewAccessor));
// 视图操作
accessor.Write(0, ref shareInfo); // 修改视图
}
}
return result;
}
#endregion 非持久文件映射
#region 持久文件映射
/*
* 2、持久文件映射
* 持久文件是与磁盘上的源文件关联的内存映射文件。
* 在最后一个进程使用完此文件后,数据将保存到磁盘上的源文件中。这些内存映射文件适合用来处理非常大的源文件。
* 不需要考虑维护共享内存对象被回收的问题
*/
/// <summary>
/// 内存共享_基于流的操作_读-持久文件映射
/// </summary>
/// <param name="mmfFile">共享内容对象的文件路径</param>
/// <param name="mmfName">共享内容对象名</param>
/// <returns></returns>
public static MemoryMappedFile_ShareInfo_ViewStream MemoryMappedFile_ViewStream_Read_Keep(string mmfFile, string mmfName, long defaultSize = 0x1100100)
{
MemoryMappedFile_ShareInfo_ViewStream resultShareInfo = new();
using (MemoryMappedFile mmf_Keep = MemoryMappedFile.CreateFromFile(mmfFile, FileMode.OpenOrCreate, mmfName, defaultSize)) // "D:\\内存映射文件.data",默认100MB
{
using (MemoryMappedViewStream stream = mmf_Keep.CreateViewStream())
{
if (stream.CanRead)
{
BinaryReader reader = new(stream);
if (JsonConvert.DeserializeObject<MemoryMappedFile_ShareInfo_ViewStream>(reader.ReadString()) is MemoryMappedFile_ShareInfo_ViewStream share)
{
resultShareInfo = share;
}
}
}
}
return resultShareInfo;
}
/// <summary>
/// 内存共享_基于内存偏移量的操作_读-持久文件映射
/// </summary>
/// <param name="mmfFile">共享内容对象的文件路径</param>
/// <param name="mmfName">共享内容对象名</param>
/// <returns></returns>
public static MemoryMappedFile_ShareInfo_ViewAccessor MemoryMappedFile_ViewAccessor_Read_Keep(string mmfFile, string mmfName, long defaultSize = 0x1100100)
{
MemoryMappedFile_ShareInfo_ViewAccessor resultShareInfo = new();
using (MemoryMappedFile mmf_Keep = MemoryMappedFile.CreateFromFile(mmfFile, FileMode.OpenOrCreate, mmfName, defaultSize)) // "D:\\内存映射文件.data",默认100MB
{
using (MemoryMappedViewAccessor accessor = mmf_Keep.CreateViewAccessor(0, 100)) // 注意这里的偏移量,大小;大小需要调整
{
int colorSize = Marshal.SizeOf(typeof(MemoryMappedFile_ShareInfo_ViewAccessor));
// 视图操作
accessor.Read(0, out resultShareInfo); // 读取视图
}
}
return resultShareInfo;
}
/// <summary>
/// 内存共享_基于流的操作_写-持久文件映射
/// </summary>
/// <param name="mmfFile">共享内容对象的文件路径</param>
/// <param name="mmfName">共享内容对象名</param>
/// <param name="share">写入的内容</param>
public static bool MemoryMappedFile_ViewStream_Wirte_Keep(string mmfFile, string mmfName, MemoryMappedFile_ShareInfo_ViewStream shareInfo, long defaultSize = 0x1100100)
{
bool result = false;
using (MemoryMappedFile mmf_Keep = MemoryMappedFile.CreateFromFile(mmfFile, FileMode.OpenOrCreate, mmfName, defaultSize)) // "D:\\内存映射文件.data",默认100MB
{
using (MemoryMappedViewStream stream = mmf_Keep.CreateViewStream())
{
result = stream.CanWrite;
if (result)
{
BinaryWriter writer = new(stream);
writer.Write(JsonConvert.SerializeObject(shareInfo));
}
}
}
return result;
}
/// <summary>
/// 内存共享_基于内存偏移量的操作_写-持久文件映射
/// </summary>
/// <param name="mmfFile">共享内容对象的文件路径</param>
/// <param name="mmfName">共享内容对象名</param>
/// <param name="share">写入的内容(二进制,单位MB)</param>
public static bool MemoryMappedFile_ViewAccessor_Wirte_Keep(string mmfFile, string mmfName, MemoryMappedFile_ShareInfo_ViewAccessor shareInfo, long defaultSize = 0x1100100)
{
bool result = false;
using (MemoryMappedFile mmf_Keep = MemoryMappedFile.CreateFromFile(mmfFile, FileMode.OpenOrCreate, mmfName, defaultSize)) // "D:\\内存映射文件.data",默认100MB
{
using (MemoryMappedViewAccessor accessor = mmf_Keep.CreateViewAccessor(0, 100)) // 注意这里的偏移量,大小;大小需要调整
{
result = accessor.CanRead;
if (result)
{
int colorSize = Marshal.SizeOf(typeof(MemoryMappedFile_ShareInfo_ViewAccessor));
// 视图操作
accessor.Write(0, ref shareInfo); // 修改视图
}
}
}
return result;
}
#endregion 持久文件映射
/// <summary>
/// 共享内存_基于流的
/// </summary>
public class MemoryMappedFile_ShareInfo_ViewStream
{
/// <summary>
/// 标识ID
/// </summary>
public string SessionIdGUID { set; get; } = string.Empty;
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { set; get; } = DateTime.Now;
/// <summary>
/// 自定义的共享信息
/// </summary>
public object InfoData { set; get; } = new object();
}
/// <summary>
/// 共享内存_基于偏移量的
/// </summary>
public struct MemoryMappedFile_ShareInfo_ViewAccessor
{
/// <summary>
/// 标识ID
/// </summary>
public int SessionIdGUID { set; get; } = 0;
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { set; get; } = DateTime.Now;
/// <summary>
/// 自定义的共享信息
/// </summary>
public long InfoData { set; get; } = 0;
public MemoryMappedFile_ShareInfo_ViewAccessor()
{
}
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
二、发送端:
/// <summary>
/// 共享内存传递_发送
/// </summary>
private void btnSedMsg_SharedMemo_Click(object sender, EventArgs e)
{
bool result = false;
if (radIsStream.Checked && chkIsKeep.Checked)
{
MemoryMappedFile_ShareInfo_ViewStream shareInfo = new();
shareInfo.SessionIdGUID = "1";
shareInfo.CreateTime = DateTime.Now;
shareInfo.InfoData = txtMsg_SharedMemo.Text.Trim();
// result = MemoryMappedFile_ViewStream_Wirte_Keep(txtShareFilePath.Text.Trim(), txtShareName.Text.Trim(), shareInfo);
result = MemoryMappedFile_ViewStream_Wirte_Keep(@"D:\ShareTest.data", @"ImgA", shareInfo);
} // 内存共享_基于流的操作_写-持久文件映射
else if (radIsStream.Checked && !chkIsKeep.Checked)
{
MemoryMappedFile_ShareInfo_ViewStream shareInfo = new();
shareInfo.SessionIdGUID = "1";
shareInfo.CreateTime = DateTime.Now;
shareInfo.InfoData = txtMsg_SharedMemo.Text.Trim();
result = MemoryMappedFile_ViewStream_Wirte_NoKeep(txtShareName.Text.Trim(), shareInfo);
} // 内存共享_基于流的操作_写-非持久文件映射
else if (!radIsStream.Checked && chkIsKeep.Checked)
{
MemoryMappedFile_ShareInfo_ViewAccessor shareInfo = new();
shareInfo.SessionIdGUID = 1;
shareInfo.CreateTime = DateTime.Now;
shareInfo.InfoData = Convert.ToInt64(txtMsg_SharedMemo.Text.Trim());
//result = MemoryMappedFile_ViewAccessor_Wirte_Keep(txtShareFilePath.Text.Trim(), txtShareName.Text.Trim(), shareInfo);
result = MemoryMappedFile_ViewAccessor_Wirte_Keep(@"D:\ShareTest.data", @"ImgA", shareInfo);
} // 内存共享_基于内存偏移量的操作_写-持久文件映射
else if (!radIsStream.Checked && !chkIsKeep.Checked)
{
MemoryMappedFile_ShareInfo_ViewAccessor shareInfo = new();
shareInfo.SessionIdGUID = 1;
shareInfo.CreateTime = DateTime.Now;
shareInfo.InfoData = Convert.ToInt64(txtMsg_SharedMemo.Text.Trim());
result = MemoryMappedFile_ViewAccessor_Wirte_NoKeep(txtShareName.Text.Trim(), shareInfo); //
} // 内存共享_基于内存偏移量的操作_写-非持久文件映射
txtMsg_SharedMemo.Text += ";" + result.ToString();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
三、接收端:
/// <summary>
/// 共享内存方式-手动获取(根据需要加互斥锁或进程内线程锁)
/// </summary>
private void BtnManualGet_Click(object sender, EventArgs e)
{
if (radIsStream.Checked && chkIsKeep.Checked) // 内存共享_基于流的操作_写-持久文件映射
{
MemoryMappedFile_ShareInfo_ViewStream shareInfo = MemoryMappedFile_ViewStream_Read_Keep(txtShareFilePath.Text.Trim(), txtShareName.Text.Trim());
if (shareInfo != null && shareInfo.InfoData is string infoData)
{
rTxtShareMemo_msg.Text = "信息序号:" + shareInfo.SessionIdGUID + ";发送时间:" + shareInfo.CreateTime + ";内容:" + (!string.IsNullOrEmpty(infoData) ? infoData : string.Empty);
}
else
{
rTxtShareMemo_msg.Text = "未获取到数据!";
}
}
else if (radIsStream.Checked && !chkIsKeep.Checked) // 内存共享_基于流的操作_写-非持久文件映射
{
MemoryMappedFile_ShareInfo_ViewStream shareInfo = MemoryMappedFile_ViewStream_Read_NoKeep(txtShareName.Text.Trim());
if (shareInfo != null && shareInfo.InfoData is string infoData)
{
rTxtShareMemo_msg.Text = "信息序号:" + shareInfo.SessionIdGUID + ";发送时间:" + shareInfo.CreateTime + ";内容:" + (!string.IsNullOrEmpty(infoData) ? infoData : string.Empty);
}
else
{
rTxtShareMemo_msg.Text = "未获取到数据!";
}
}
else if (!radIsStream.Checked && chkIsKeep.Checked) // 内存共享_基于内存偏移量的操作_写-持久文件映射
{
MemoryMappedFile_ShareInfo_ViewAccessor shareInfo = MemoryMappedFile_ViewAccessor_Read_Keep(txtShareFilePath.Text.Trim(), txtShareName.Text.Trim());
rTxtShareMemo_msg.Text = "信息序号:" + shareInfo.SessionIdGUID + ";发送时间:" + shareInfo.CreateTime + ";内容:" + (long)shareInfo.InfoData;
}
else if (!radIsStream.Checked && !chkIsKeep.Checked) // 内存共享_基于内存偏移量的操作_写-非持久文件映射
{
MemoryMappedFile_ShareInfo_ViewAccessor shareInfo = MemoryMappedFile_ViewAccessor_Read_NoKeep(txtShareName.Text.Trim()); //
rTxtShareMemo_msg.Text = "信息序号:" + shareInfo.SessionIdGUID + ";发送时间:" + shareInfo.CreateTime + ";内容:" + (long)shareInfo.InfoData;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
作者:꧁执笔小白꧂