C#:在多个进程和/或线程之间共享数据的最佳方法

时间:2018-10-17 19:18:54

标签: c# multithreading multiprocessing ipc data-sharing

C#Restful Web服务(在Windows Server 2012 Standard上)需要通过我在同一服务器上运行的C#套接字服务器程序将命令发送到设备。当Web服务尝试将命令发送到所选设备时,关联设备的线程可以提取命令并将其发送到该设备。选中后,应将此线程删除它。同时,与设备n相关联的线程n也可以拾取设备n的命令,并且在该命令被拾取并发送后,线程n可以删除该命令。请参考下面的系统架构图。

我的问题是,允许Web服务发送命令数据的最佳方法(最有效,最可靠的解决方案)是什么,那些套接字线程可以选择与它们关联的命令,然后在发出命令后删除这些命令?这些命令可以保存到数据库中,套接字线程可以定期检查数据库,但这不是有效的方法,尤其是在设备和用户数量很大的情况下。命名管道是否适合这种情况,线程可以检查这些Pipe实例以找到关联的命令?

System architecture image

3 个答案:

答案 0 :(得分:0)

Windows服务可以具有一个附加的套接字侦听器(或类似的侦听器),以接收任何已连接设备的命令,并为每个设备维护BlockingCollection。拥有与每个设备的连接的线程可以简单地在从BlockingCollectoion接收消息并在其套接字上与该设备进行交互时循环。

答案 1 :(得分:0)

我将在这里补充我的评论-这是一个常见的情况,一些主要的软件公司(Azure,Amazon,Apache)已经实现了解决方案。它们都具有多个发件人的概念,发送到单个消息代理,然后该代理将每个消息直接转发到预期的收件人。为了使每个收件人都可以接收消息,他们必须连接到消息代理,并声明他们是谁(或感兴趣的消息)。

重要的是要注意,消息代理对于服务器间的通信来说很常见,但是同一台机器上的进程间通信有更多的选择(通常更简单,更有效)。因此,在选择解决方案之前,您需要考虑您的设备是否将始终与单个套接字服务器通信,或者是否会在某个时候扩展到多个实例。

使用第三方消息代理的一些优点:

  • 它们可以为当前未连接的收件人缓冲邮件
  • 其中大多数提供了易于使用的C#程序包,因此几乎不需要任何设置
  • 他们通常提供99.99%或更高正常运行时间的SLA

与同一主机上的纯进程间解决方案相比,有一些缺点:

  • 由于与外部消息代理服务器的通信,它们具有更高的延迟时间
  • 由于与外部服务器的通信,它们的最大吞吐量较低。
  • 它们通常要花钱(有时可以免费发送100,000条消息)

答案 2 :(得分:0)

使用您的数据库

有很多方法可以执行此操作,例如-Memory mapped filesAnonymous pipesMSMQ,举三个例子。但是最简单的方法是使用数据库。具体来说,我会这样:

  1. 定义数据库表,这些表的结构使其可以保存您希望用户能够更改或发送的设备列表或命令。例如,您可能有一个列出每个用户设备的表,或者包含要发送到设备的命令队列的表。

  2. 对Web服务进行编程以更新数据库。例如,当用户想要“发送”命令时,只需将其添加到表中即可。不用担心硬件。

  3. 编写Windows服务(或修改现有服务)以偶尔阅读 数据库并“同步”所有内容,例如发送任何待处理的消息到设备。同步后,将标志写回到数据库,以便Web服务可以读取它并告诉用户命令已处理或更新已完成。

这将为您提供一个简单,容错的解决方案,而不会在您的体系结构中引入任何新技术。

通过存储硬件快照,您还可以为各种有趣的可能性提供扩展点,例如“撤消”功能,保存的快照或客户支持工具(可让您查看最终用户要设置的内容)或营销分析工具(可让您查看用户如何使用产品)。

但是最重要的功能是,您可能会崩溃/重新启动所有服务,并且该解决方案将在中断的地方继续进行。因此也很容易支持。希望您已经知道如何使用数据库。