我找不到任何有用的答案,虽然已经多次以不同的方式询问过这个问题。
我想在两个进程(两个不同的应用程序)之间共享内存, 这样他们中的一个可以写入该内存而另一个可以读取。
这在.NET中可行吗?怎么样?
由于
答案 0 :(得分:29)
目前,.NET不支持部分(也称为内存映射文件)。很快,4.0版本将具有System.IO.MemoryMappedFiles命名空间。有这么好的理由花了这么长时间,也是你不会对这种添加感到满意的原因。在MMF中必须使用指针,共享内存在特定地址可用。要共享一个值,您必须将其写入特定地址。
然而,指针与托管内存模型根本不兼容。对象在垃圾收集堆中创建,收集器根据需要移动它们以保持堆压缩。在托管语言中,您可以引用此类对象,也称为“跟踪句柄”。 C / C ++等价物是一个指针,但它是一个带有铃声的指针,垃圾收集器总能找回它并更新它的值。 CLR确实支持“固定”的概念,它将引用转换为指针。它通过将对象标记为不可移动来实现此目的。但是,这无助于通过MMF实现共享内存,该对象固定在GC堆中,而不是MMF视图所在的虚拟内存地址。
要使MMF正常工作,需要将对象从GC堆复制到共享内存。这需要序列化。 .NET 4.0类名为MemoryMappedViewStream。您可能会看到它的位置,这与使用命名管道或套接字无法区分。将数据输入和输出MMF需要花费相同的精力。 MMF仅略高一些,因为底层缓冲区不在内核内存池中。
你可以打破规则,今天就这样做。您可以P / Invoke创建MMF所需的CreateFileMapping,OpenFileMapping和MapViewOfFile。并使用unsafe关键字,以便您可以创建指针。您需要为共享内存元素使用值类型(如struct)或使用Marshal类。
答案 1 :(得分:4)
<强> IPC 强>
如果您正在谈论Inter Process Communication。有几种可能性,比如使用tcp / udp套接字,邮件槽,命名管道,内存映射文件,Windows消息等。
.Net还提供了一些更高级别的IPC,如.Net remoting和WCF,它们使用前面提到的技术。您可以阅读更多相关信息here。
内存映射文件
如果你真的想共享一块内存而不是通信,那么内存映射文件就是你想要的。 .Net 4.0有MemoryMappedFile。如果您没有或不能使用.Net 4.0,您可以自己实现它,就像在win32 example中一样。或者您可以尝试this代码或查看是否可以使用提到here和here的MemoryMappedFileStream。或者使用此FileMap类。
答案 2 :(得分:1)
使用named pipe。
这是一种允许一个进程将顺序数据写入流中的机制,其他进程可以从中读取。
请注意,命名管道仅允许顺序读取。如果您需要使用更详细的查询,则可能需要使用客户端 - 服务器体系结构。在这种情况下,阅读器进程使用network sockets查询其他进程以获取信息。
答案 3 :(得分:0)
如前所述,使用内存映射文件。
.NET的实现&lt; 4可在以下网址获得:http://github.com/tomasr/filemap/
我已经习惯了,它完美无瑕。在提升/未提升的进程之间共享时可能会遇到一些安全问题 - 解决方案是在提升的进程中初始化内存映射文件并相应地设置其安全属性。
答案 4 :(得分:0)