首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于.NET多agent仿真的插件体系结构(运行时加载/卸载)

用于.NET多agent仿真的插件体系结构(运行时加载/卸载)
EN

Stack Overflow用户
提问于 2014-01-22 02:02:28
回答 2查看 773关注 0票数 2

描述

我目前正在为C#多agent模拟设计一个体系结构,其中代理操作由其“大脑”中的许多模块驱动,这些模块可以读取传感器、投票选择动作或向其他模块发送消息/查询(所有这些都是通过消息交换实现的)。当然,模块可以有一个状态。

模块在并行中运行:它们有一个更新方法,它使用消息和查询,并执行某种计算。update方法返回迭代器,并且在它们的主体中有多个输出,这样我就可以协作地调度模块。我不对每个模块使用一个线程,因为我希望每个代理都有数百到数千个模块,这将导致线程开销占用大量RAM。

我希望这些模块的行为类似于运行时插件,这样在仿真运行时,我可以添加新的模块类并重写/调试现有的模块,而不需要停止模拟过程,然后使用这些类从代理的大脑中添加和删除模块,或者只允许现有模块由于其方法的新实现而改变其行为。

可能的解决方案

在过去几天里,我提出了一些可能的解决办法,但都有些令人失望的地方:

  1. 将我的模块编译成DLL,将每个模块加载到不同的AppDomain中,然后使用AppDomain.CreateInstanceFromAndUnwrap()实例化模块,然后将该模块转换为一些IModule接口,在模拟和模块之间共享(并由每个模块类实现)。该接口只公开所有模块共有的SendMessage、更新和其他几个成员。
代码语言:javascript
复制
- The problem with this solution is that calls between AppDomains are much slower than direct calls (within the same AppDomain).
- Also, I don't know the overhead of AppDomains, but I suppose that they are not free, so having thousands could become a problem.

  1. 对模块使用一些脚本语言,同时为底层引擎保留C#,这样就没有程序集的加载/卸载。相反,我将为每个模块的脚本语言托管一个执行上下文。
代码语言:javascript
复制
- My main concern is that I do not know a scripting language which is **big** (as in 'python, lua, ruby, js are big, Autoit and Euphoria are not') **fast**, **embeddable into .NET** and allows **step by step execution** (which I need in order to perform cooperative scheduling of module execution).
- Another concern about this is that I suppose I'd have to use a runtime context for each module, which in turn would have massive overhead.
- Lastly, I suppose a scripting language would be probably slower than C#, which would reduce performance.

  1. 避免卸载程序集,而不是以某种方式renaming/versioning它们,这样我就可以拥有大量不同的版本,然后只需对每种类型使用最新的版本。
代码语言:javascript
复制
- I'm not even sure this is possible (due to omonimous types and namespaces)
- Even if possible, it would be very memory-inefficient.

  1. 执行模拟的透明重新启动,这意味着暂停仿真(并执行大脑/模块调度器)、序列化所有内容(包括每个模块)、退出模拟、重新编译代码、再次启动模拟、反序列化所有操作、捕获由于对类所做的更改而引发的异常并继续执行。
代码语言:javascript
复制
- This is a lot of work, so I consider it my last resort.
- Also, this whole process would be very slow at some point, depending on number of modules and their sizes, making it impractical

我可以克服最后一个问题(解决方案4的整个过程变得缓慢),方法是将解决方案3和4混合起来,将许多程序集加载到某种形式的版本控制中,并不时地执行重新启动来清理混乱。然而,我希望不要仅仅因为我在模块类中做了一个小小的更改而中断整个模拟。

实际问题

因此,我的问题是:还有其他解决办法吗?我有没有错过任何解决我发现的问题的方法?例如,是否有一些.NET脚本语言可以满足我的需求(解决方案2)?以我模糊描述的方式(解决方案#3),版本控制可能吗?

或者更简单地说:.NET是这个项目的错误平台吗?(我想坚持这样做,因为C#是我的主要语言,但我可以看到自己用Python或其他类似的语言(如果需要的话)这样做。)

EN

回答 2

Stack Overflow用户

发布于 2014-01-22 02:15:54

你认为托管扩展框架

票数 1
EN

Stack Overflow用户

发布于 2016-12-11 16:33:24

我在一个模拟系统中工作,它以非常类似的方式工作,将代理模块作为插件处理。

我创建了一个插件管理器,它处理每个域加载相关的事情,检查虚拟域中的插件有效性,然后将其热加载到引擎域中。

使用AppDomain可以获得完整的控制,并且可以通过并行运行插件管理器的任务来减少进程时间。

AppDomains并不是免费的,但是您只能使用两个(或者三个,如果您需要更多地隔离验证和执行域)来处理它。

一旦验证了一个插件文件,您就可以随时在主进程中加载它,在任何域的探测路径(如果设置为动态路径)中创建一个影子副本,并以它为目标,而不是原始文件,这对于检查版本控制和更新非常有用。

使用域进行验证和执行另一个域可能需要交换上下文,后者在更新时负责处理以前的版本实例。

保持一个时间计划任务来检查新插件和新版本,然后阻止插件模块的使用、交换文件、重新加载和取消阻塞,必要时从以前的版本中恢复新版本。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21272784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档