在同一台计算机上的.net应用程序之间传输大数据

我有两个在同一台机器上运行的.net应用程序。 第一个应用是’引擎’。 它构建图像 – 图像的大小约为4M。 第二个应用程序是“查看器”。 它显示了“引擎”发送的图像。 引擎每10-15秒发送一次图像。

我的问题是将图像从引擎传递给观看者的麻烦方法是什么。 目前,我正在使用FileSystem。 引擎将映像写入文件系统文件夹,并使用FileSystemWatcher将查看器获取此文件。

那方法好吗? 这可靠吗?

有很多好的选择:

  • 消息队列
  • 命名管道(直接)
  • 内存映射文件
  • 命名管道或MSMQ上的WCF

其中任何一个都足够快,所以我建议最容易实现。

在我看来,Message Queue(MSMQ)最简单易用,为您提供对象传输(而不是流),并为您提供可选的传输持久性(在发送方或接收方未运行的情况下非常有用)。 所有这些对于WCF而不是MSMQ都是如此,但WCF意味着更多的开销,复杂性和配置,并且没有额外的(在这种情况下)值。

像这样发送:

MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue"); Message msg = new Message { Formatter = new BinaryMessageFormatter(), Body = myImage, Label = "Image" }; queue.Send(msg); 

接收:

 MessageQueue queue = new MessageQueue(".\\private$\\ImagesQueue"); msg = queue.Receive(TimeSpan.FromMilliseconds(100)); if (msg != null) { msg.Formatter = new BinaryMessageFormatter(); myImage = (MyImage)msg.Body; } 

需要在使用前创建队列。 您可以在应用程序启动时执行此操作

在你的课堂上有这个:

 private const string queueName = ".\\private$\\ImagesQueue"; 

在应用程序初始化/启动时,请确保您有队列:

 if (!MessageQueue.Exists(queueName) { MessageQueue myQueue = MessageQueue.Create(queueName); } 

使用此队列机制,Engine无需等待Viewer完成。 这将大大提高感知性能,因为您可以生成下一个图像(实际上是它们的数量),而前一个图像仍在查看中。 使用内存映射文件实现起来并不容易。

MSMQ是标准Windows组件,但需要在Windowsfunction中启用。

由于.NET Framework 4.0可以使用内存映射文件,因此我认为它比基于文件系统的方法更快,因为您不需要昂贵的文件系统IO操作。

内存映射文件包含虚拟内存中文件的内容。 文件和内存空间之间的这种映射使应用程序( 包括多个进程 )能够通过直接读取和写入内存来修改文件。 内存映射文件可以跨多个进程共享 。 进程可以使用由创建该文件的进程分配的公用名映射到>相同的内存映射文件

因此,要在多个进程之间共享MMF,您只需要共享一个MMF名称,这样您就可以考虑以下方法:

  • 引擎创建MMF文件并与Viewer共享一个名称(字符串)
  • 使用MemoryMappedFile.OpenExisting(sharedName)方法查看访问MMF (有关从不同进程访问相同MMF的示例,请参阅MSDN )

有用的链接:

  • 内存映射文件
  • 在.NET 4中使用内存映射文件 – 强烈建议阅读本文,该文章描述了为什么MMF真的"is the most efficient way for multiple processes on a single machine to communicate with each other" 。 基本上它表明所有其他IPC选项都是基于MMF的。

(来自上面提到的文章)如果我们检查其他IPC方法,我们可以看到以下架构: 在此处输入图像描述

是的,这是一种有效的方法。 并假设您的代码不包含错误,是的,它是可靠的。

但它很慢。 如果需要考虑吞吐量,则可能需要使用套接字(如果您希望将引擎和查看器拆分为不同的计算机)或命名管道(用于同一台计算机上的进程间通信)。

使用ZeroMQ 。 它非常易于使用(如果您只发送一种消息,则比WCF更容易),没有很多开销,并且通常是许多进程间通信问题的良好解决方案。