Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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
.net 架构:如何为访问共享资源的多个COM接口提供服务_.net_Design Patterns_Architecture_Ipc_Interprocess - Fatal编程技术网

.net 架构:如何为访问共享资源的多个COM接口提供服务

.net 架构:如何为访问共享资源的多个COM接口提供服务,.net,design-patterns,architecture,ipc,interprocess,.net,Design Patterns,Architecture,Ipc,Interprocess,我有一个建筑问题。我有一个项目在概念上是这样的: 这看起来很简单,但也有皱纹。一些背景,通过一个部分虚构的例子。这是一个控制一些电机、传感器和一些电源开关的控制器。硬件设备可以旋转观测圆顶并报告其位置,打开和关闭快门,打开和关闭各种观测仪器(望远镜、照相机、调焦器等)的电源 硬件抽象层处理通过串行链路发送和接收命令以及由此带来的任何定时和排序问题。表示层可以调用HAL中的方法,使硬件执行某些操作,这可能会在串行端口上生成一系列命令和响应,或者根本没有。未经请求的数据也可以到达串行端口,并在HA

我有一个建筑问题。我有一个项目在概念上是这样的:

这看起来很简单,但也有皱纹。一些背景,通过一个部分虚构的例子。这是一个控制一些电机、传感器和一些电源开关的控制器。硬件设备可以旋转观测圆顶并报告其位置,打开和关闭快门,打开和关闭各种观测仪器(望远镜、照相机、调焦器等)的电源

硬件抽象层处理通过串行链路发送和接收命令以及由此带来的任何定时和排序问题。表示层可以调用HAL中的方法,使硬件执行某些操作,这可能会在串行端口上生成一系列命令和响应,或者根本没有。未经请求的数据也可以到达串行端口,并在HAL中完全处理

“表示层”由几个COM接口组成。一个接口(IDome)负责控制圆顶和快门,另一个接口(IPower)负责控制各种设备的电源。这是一个标准,不能改变

当两个不同的程序想要访问设备时,就会出现问题。例如,一个程序可能希望通过IDome接口控制dome,另一个程序可能希望使用IPower接口控制电源。在当前的实现中,这将导致在不同的进程中创建整个程序集的两个实例,其中一个由于串行端口上的争用而失败,串行端口只能允许一个连接

我需要找到一种将HAL和表示层解耦的方法,这样COM接口可以由多个进程加载,而HAL只加载一次并为表示层的所有实例提供服务

目前,所有这些“层”都包含在一个.NET程序集中,如果可能的话,我更愿意保持这种方式


什么模式适合这种情况?非常感谢您的任何建议。

一个选择是将需要成为单例(HAL)的内容实际上变成盒子上的单例。例如,您可以将HAL逻辑移动到windows服务中,表示层可以通过进程间通信(管道或tcp套接字)进行通信。为了确保只有一个服务实例启动,您可以强制使用静态服务名称,但也可以通过让服务使用系统范围的互斥来防止在多个用户会话下运行的服务实例。

您可以使用。其思想是将CLSID注册为进程外服务器(可选使用)。当您的客户端创建这些CLSID的实例时,它们都将在“代理进程”中创建,Windows将透明地封送客户端进程与此代理进程之间的调用

请注意,要执行此操作,您的接口必须具有“”。如果编译包含接口定义的IDL文件,它将为此类代理/存根DLL生成C代码。然后必须注册此DLL以进行进程外通信,才能与自定义接口正常工作


或者,您可以在HAL级别应用相同的进程外激活模型—即,为HAL创建COM接口,将HAL的CLSID注册为进程外服务器,并让内部组件通过DCOM进行通信。这样做的好处是,您可以控制接口CLSID,并且可以注册您自己的代理/存根DLL,而不可能与其他供应商的代理/存根DLL发生冲突。

就模式而言,您需要一个控制对HAL的所有访问的代理,这是一个给定的

就控制访问而言,多个UI控制一组资源有意义吗?假设您也需要,代理将使用逻辑来解决冲突等

或者,代理有两个逻辑部分,一个接受输入,另一个报告当前值,以便多个订户客户机(UI)能够及时了解HAL所在的位置。事件驱动的方法在这里可以很好地工作,还可以看看发布/订阅模式。对于单个控件,请查看锁定模式


在所有情况下,代理都是应用控制逻辑的地方,但代码结构本身要比这复杂得多。

Hmm,那么当两个程序都想使用IDome时,会发生什么呢?这往往会很快以与SerialPort处理它完全相同的方式结束:先到先服务,拒绝其他人访问。这并没有那么糟糕,因为HAL实际上主要处理缓存数据,所以实际上没有资源争用。唯一的争论点实际上来自HAL必须打开串行端口这一事实。此外,在这种特殊情况下,多个程序访问同一接口是不正常的,多个程序将分别访问不同的接口。这种体系结构中的一些已经有10多年的历史了,并且比.NET早,所以它有点不合适。一个程序使用IDome来成像月球,另一个程序使用IDome来成像火星。这怎么会有个好结局呢?存在资源争用,只有一个dome。如果您有一个集中的进程来控制它,请求不仅可以指定目标(Mars),还可以指定源。如果位置不再是源,则可以提供一个良好的错误。通过这种方式,有人可以请求拍摄火星图像,但只有在客户和用户明确地将其从月球上移开之后,这似乎是一个合理的解决方案。您将如何处理IPC方面的问题?是否有必要将所有内容作为字符串传递,或者(比如).NET远程处理是一种选择?或者说,这些天来远程通信是通行证吗?我想我要问的是,‘有没有一种方法可以直接调用int