Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在同一台计算机上的.net应用程序之间传输大型数据_C#_.net_Filesystems_Communication_Filesystemwatcher - Fatal编程技术网

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

C# 在同一台计算机上的.net应用程序之间传输大型数据,c#,.net,filesystems,communication,filesystemwatcher,C#,.net,Filesystems,Communication,Filesystemwatcher,我有两个在同一台机器上运行的.net应用程序。 第一个应用程序是“引擎”。它构建图像-图像的大小约为4米。 第二个应用程序是“查看器”。它显示“引擎”发送的图像。 发动机每10-15秒发送一次图像 我的问题是,将图像从引擎传递到查看器的最基本方式是什么。 目前,我正在为此使用文件系统。引擎将图像写入文件系统文件夹,查看器使用FileSystemWatcher获取该文件 这种方法行吗?这可靠吗?由于.NET Framework 4.0可以使用内存映射文件来实现这一点,我相信这将比基于文件系统的方法

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

我的问题是,将图像从引擎传递到查看器的最基本方式是什么。 目前,我正在为此使用文件系统。引擎将图像写入文件系统文件夹,查看器使用FileSystemWatcher获取该文件


这种方法行吗?这可靠吗?

由于.NET Framework 4.0可以使用内存映射文件来实现这一点,我相信这将比基于文件系统的方法更快,因为您不需要昂贵的文件系统IO操作

内存映射文件包含虚拟内存中的文件内容 记忆。文件和内存空间之间的这种映射使 应用程序,包括多个进程,通过 直接读写到内存中。 内存映射文件可以跨多个进程共享。进程可以使用创建该文件的进程分配的公用名称映射到>相同的内存映射文件

<> P>因此,在多个进程之间共享MMF只需要共享MMF名称,因此可以考虑以下方法:

  • 引擎创建MMF文件并与查看器共享一个名称(字符串)
  • 使用方法查看访问MMF(请参阅从不同进程访问相同MMF的示例)
有用链接:

  • -强烈建议阅读这篇文章,它描述了为什么MMF真的是一台机器上多个进程相互通信的最有效方式“。基本上,它表明所有其他IPC选项都是基于MMF的
(来自上述文章)如果我们检查其他IPC方法,我们可以看到以下体系结构:
有很多好的选择:

  • 消息队列
  • 命名管道(直接)
  • 内存映射文件
  • 命名管道或MSMQ上的WCF
其中任何一个都足够快,所以我建议最容易实现

在我看来,消息队列(MSMQ)使用起来最简单,它为您提供了对象传输(与流相反),并为您提供了可选的传输持久性(在发送方或接收方未运行的情况下很有用)。所有这些对于MSMQ上的WCF都是正确的,但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);
}
使用此队列机制,引擎不必等待查看器完成。这将大大提高感知性能,因为您可以在仍在查看前一张图像时生成下一张图像(实际上是其中的数量)。使用内存映射文件不太容易实现


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

是的,这是一种有效的方法。假设你的代码不包含bug,是的,它是可靠的


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

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

似乎需要使用IPC:这是如何解决问题的?WCF增加了相当多的开销,特别是当它需要托管在进程中时。它可能会增加开销,但它是跨进程通信的有效替代解决方案。也就是说,我认为这是一种替代方案,不一定是对当前文件系统使用的改进。IPC设计用于在进程之间传输数据。我认为文件系统不可靠。你们可能会被文件锁卡住,你们可能并没有足够的可用空间等等。而且文件系统观察者也不是很可靠:在这里学究气。。。您自己的单元测试应该证明它是否正常可靠。谢谢。我喜欢Message Queue aproach,因为您写道:“我认为Message Queue(MSMQ)使用起来最简单,它为您提供了对象传输(相对于流),并为您提供了可选的传输持久性(在发送方或接收方未运行的情况下很有用)。”谢谢。很高兴能为您提供帮助。我已经用更多关于如何在应用程序启动时创建队列的细节扩展了我的答案。我不认为ZMQ在这种情况下是一个很好的选择——当你有许多小消息被发送时,ZMQ是很好的选择——并且接收它们的顺序不需要保证(甚至不需要保证它们到达)。对于股票行情每秒更新60次这样的东西很有用。在本例中,虽然我们每10-15秒发送一条非常大的消息,但ZMQ并不适合此用例。是的,但您在同一台机器上的两个组件之间发送消息。您不会遇到与UDP相关的任何数据丢失。