Skip to content

C# 进程间数据共享的简单实现

Published: at 17:31

通过内存共享(MemoryMappedFiles)实现进程间的数据共享与传递。

以下是代码辅助类

可以通过对数据的序列化来实现复杂数据的共享与传递

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Utils
{
/// <summary>
/// 用于进程间通过内存共享数据
/// </summary>
public class MemoryShare
{
#region static
private static readonly object LockHelper = new object();
private static volatile Dictionary<string,MemoryShare> _memoryMapNames = new Dictionary<string, MemoryShare>();
/// <summary>
/// 使用指定的<see cref="memoryMapName"/>创建或获取一个<see cref="MemoryShare"/>
/// </summary>
/// <param name="memoryMapName">内存文件页名称</param>
/// <param name="memoryCapacity">内存页容量大小(byte)</param>
public static MemoryShare Create(string memoryMapName, long memoryCapacity = 1024)
{
if (string.IsNullOrWhiteSpace(memoryMapName))
{
throw new ArgumentNullException(nameof(memoryMapName));
}
// ReSharper disable once InconsistentlySynchronizedField
if (!_memoryMapNames.ContainsKey(memoryMapName))
{
lock (LockHelper)
{
if (!_memoryMapNames.ContainsKey(memoryMapName))
{
var memoryShare = new MemoryShare(memoryMapName, memoryCapacity);
_memoryMapNames.Add(memoryMapName, memoryShare);
}
}
}
// ReSharper disable once InconsistentlySynchronizedField
return _memoryMapNames[memoryMapName];
}
#endregion
#region private
private readonly MemoryMappedFile _memoryMappedFile;
private readonly Mutex _mutex;
private MemoryShare(string memoryMapName, long memoryCapacity)
{
_memoryMappedFile = MemoryMappedFile.CreateOrOpen(memoryMapName, memoryCapacity, MemoryMappedFileAccess.ReadWrite);
_mutex = new Mutex(false, $"{memoryMapName}_memoryshare_mutex", out bool mutexCreated);
}
#endregion
#region public
/// <summary>
/// 将<see cref="value"/>写入共享内存中(将覆盖现有的)
/// </summary>
/// <param name="value">要写入共享内存中的内容,为空不写入</param>
public void Write(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return;
}
try
{
_mutex.WaitOne();
using (MemoryMappedViewStream stream = _memoryMappedFile.CreateViewStream())
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(value);
}
}
}
finally
{
_mutex.ReleaseMutex();
}
}
/// <summary>
/// 读取共享内存中的内容
/// </summary>
/// <returns></returns>
public string Read()
{
string result;
try
{
_mutex.WaitOne();
using (MemoryMappedViewStream stream = _memoryMappedFile.CreateViewStream())
{
using (var reader = new BinaryReader(stream))
{
result = reader.ReadString();
}
}
}
finally
{
_mutex.ReleaseMutex();
}
return result;
}
public void Clear()
{
try
{
_mutex.WaitOne();
using (MemoryMappedViewStream stream = _memoryMappedFile.CreateViewStream())
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(string.Empty);
}
}
}
finally
{
_mutex.ReleaseMutex();
}
}
#endregion
}
}

参考资料


原文链接: https://blog.jgrass.cc/posts/data-share-over-progress-csharp/

本作品采用 「署名 4.0 国际」 许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。