在C#中,实现多个程序之间的内存共享
本帖最后由 shiy720 于 2025-3-6 23:33 编辑在C#中,实现多个程序之间的内存共享和消息循环可以通过 内存映射文件(Memory-Mapped Files) 结合 事件(Event) 或 信号量(Semaphore) 来实现。以下是一个完整的示例,展示如何实现多个程序之间的内存共享和消息循环。
我们可以将共享内存和消息循环的逻辑封装到一个单独的 `SharedMemoryMessageQueue` 类中,以便更好地复用和管理代码。以下是一个完整的实现:
### 封装后的消息类
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Text.Json;
using System.Threading;
public class SharedMemoryMessageQueue : IDisposable
{
private const int BufferSize = 1024; // 共享内存缓冲区大小
private const string DefaultMapName = "SharedMemoryMap";
private const string DefaultEventName = "SharedMemoryEvent";
private readonly string _mapName;
private readonly string _eventName;
private readonly MemoryMappedFile _mmf;
private readonly EventWaitHandle _eventHandle;
public SharedMemoryMessageQueue(string mapName = DefaultMapName, string eventName = DefaultEventName)
{
_mapName = mapName;
_eventName = eventName;
// 创建或打开内存映射文件
_mmf = MemoryMappedFile.CreateOrOpen(_mapName, BufferSize);
// 创建或打开事件
_eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, _eventName);
}
/// <summary>
/// 发送消息到共享内存
/// </summary>
public void SendMessage<T>(T message)
{
// 序列化消息
string json = JsonSerializer.Serialize(message);
byte[] buffer = Encoding.UTF8.GetBytes(json);
if (buffer.Length > BufferSize - sizeof(int))
{
throw new InvalidOperationException("Message is too large for the shared memory buffer.");
}
// 写入共享内存
using (var accessor = _mmf.CreateViewAccessor())
{
accessor.Write(0, buffer.Length); // 写入消息长度
accessor.WriteArray(sizeof(int), buffer, 0, buffer.Length); // 写入消息内容
}
// 通知接收方
_eventHandle.Set();
}
/// <summary>
/// 从共享内存接收消息
/// </summary>
public T ReceiveMessage<T>()
{
// 等待发送方的通知
_eventHandle.WaitOne();
// 读取共享内存
using (var accessor = _mmf.CreateViewAccessor())
{
int length = accessor.ReadInt32(0); // 读取消息长度
byte[] buffer = new byte;
accessor.ReadArray(sizeof(int), buffer, 0, length); // 读取消息内容
// 反序列化消息
string json = Encoding.UTF8.GetString(buffer);
return JsonSerializer.Deserialize<T>(json);
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
_mmf?.Dispose();
_eventHandle?.Dispose();
}
}
### 使用示例
#### 发送消息的程序(Producer)
using System;
class Producer
{
static void Main()
{
using (var messageQueue = new SharedMemoryMessageQueue())
{
while (true)
{
Console.WriteLine("Enter a message (or 'exit' to quit):");
string input = Console.ReadLine();
if (input.ToLower() == "exit")
break;
// 发送消息
var message = new { Sender = "Producer", Content = input, Timestamp = DateTime.UtcNow };
messageQueue.SendMessage(message);
Console.WriteLine("Message sent.");
}
}
}
}
#### 接收消息的程序(Consumer)
using System;
class Consumer
{
static void Main()
{
using (var messageQueue = new SharedMemoryMessageQueue())
{
while (true)
{
Console.WriteLine("Waiting for a message...");
// 接收消息
var message = messageQueue.ReceiveMessage<SharedMessage>();
Console.WriteLine($"Received message from {message.Sender} at {message.Timestamp}: {message.Content}");
}
}
}
}
// 定义消息格式
public class SharedMessage
{
public string Sender { get; set; }
public string Content { get; set; }
public DateTime Timestamp { get; set; }
}
### 运行步骤
1. 启动 **Consumer** 程序,它会等待消息。
2. 启动 **Producer** 程序,输入消息并发送。
3. **Consumer** 程序会接收到消息并显示。
### 关键点
1. **封装共享内存和事件**:将共享内存和事件的逻辑封装到 `SharedMemoryMessageQueue` 类中,简化了使用。
2. **泛型支持**:`SendMessage` 和 `ReceiveMessage` 方法支持泛型,可以发送和接收任意类型的消息。
3. **资源管理**:实现了 `IDisposable` 接口,确保共享内存和事件句柄的正确释放。
4. **线程安全**:通过事件实现了进程间的同步,确保消息的正确传递。
### 扩展功能
- **超时机制**:可以为 `ReceiveMessage` 方法添加超时参数,避免无限等待。
- **错误处理**:增加对共享内存和事件的错误处理,确保程序的健壮性。
- **多消费者**:可以使用多个事件或信号量来实现多个消费者。
### 总结
通过封装共享内存和事件逻辑,我们实现了一个简单且易用的消息队列类 `SharedMemoryMessageQueue`。它可以用于多个程序之间的高效通信,适用于需要高性能和低延迟的场景。
页:
[1]