C# AKKA.NET问题:在一个应用程序中有多个ActorSystem是一个好主意吗?

C# AKKA.NET问题:在一个应用程序中有多个ActorSystem是一个好主意吗?,c#,akka.net,C#,Akka.net,我正在为C#桌面应用程序(不是服务器而是桌面GUI应用程序)编写插件。 为了简化线程问题,我正在研究是否可以在这些插件中使用AKKA.NET。 这些插件基本上是相互独立的。 因此,从架构的角度来看,给每个插件提供自己的“私有”ActorSystem实例是很自然的。 这种方法的优点是插件最大限度地彼此隔离。 另一方面,我读了一些关于Akka for the JVM的文章,这些文章告诉我,应用程序中有太多ActorSystem实例是一种反模式,因为ActorSystem相当重 并发插件的实际数量是1

我正在为C#桌面应用程序(不是服务器而是桌面GUI应用程序)编写插件。 为了简化线程问题,我正在研究是否可以在这些插件中使用AKKA.NET。 这些插件基本上是相互独立的。 因此,从架构的角度来看,给每个插件提供自己的“私有”ActorSystem实例是很自然的。 这种方法的优点是插件最大限度地彼此隔离。 另一方面,我读了一些关于Akka for the JVM的文章,这些文章告诉我,应用程序中有太多ActorSystem实例是一种反模式,因为ActorSystem相当重

并发插件的实际数量是10-20个,即应用程序最多可以有20个ActorSystem实例在内部运行。同样,这是一个GUI桌面应用程序,通常在终端服务器会话中运行(即,可能有许多GUI应用程序在终端服务器上运行)

那么,这种简单化的方法(每个库一个ActorSystem)是否成立?或者设计一种使用全局ActorSystem的方法更好,它使用每个插件的顶级参与者来隔离插件。 这种方法对于性能来说可能更好,但我有点担心,因为插件之间并不是孤立的


那么,这种“多系统”方法是一种好的体系结构方法,还是坚持“一个全球系统”设计更好?您在这里的经历是什么?

如果隔离是您的目标,那么多参与者系统无法解决您的问题-
ActorSystem
只是一个普通类,您仍然可以使用静态字段共享数据,并且(可能)如果您有足够的决心,您仍然可以访问其他参与者系统。所以,若您运行不受信任的代码,actor系统将不会帮助您

通过在旧的.NET框架或.NET核心中使用,可以实现.NET中真正的进程内隔离

请记住,使用actor编程范式是一项严肃的设计决策,可以通过多种方式实现组件隔离。因此,如果组件隔离是您决定使用actor的唯一原因,那么您可能需要注意并重新考虑其他选项

Akka.NET扩展 您可以使用actor-per-plugin,甚至使用本机Akka.NET扩展——这是一种允许我们为Akka本身构建插件的机制。几乎Akka的每一个更高级别的特性都是作为扩展构建的:集群、远程处理、集群切分、持久性等

要构建扩展,您需要两个类:

公共类MyExtensionProvider:ExtensionProvider
{
公共覆盖MyExtension CreateExtension(ExtendedActorSystem)=>
新MyExtension(系统);
}
公共类MyExtension:IEExtension
{
公共MyExtension(ExtendedActorSystem系统){}
}
您可以通过:
actorSystem.WithExtension()
(也可以签出该方法的覆盖)从代码本身注册和检索这些扩展。您也可以直接在HOCON中注册它们-通过HOCON配置提供时,它们将在系统启动时自动启动:

akka.extensions = [
    "MyNamespace.MyExtensionProvider1, MyAssembly",    
    "MyNamespace.MyExtensionProvider2, MyAssembly"
]
那么,这种简单化的方法(每个库一个ActorSystem)是否成立?或者设计一种使用全局ActorSystem的方法更好,它使用每个插件的顶级参与者来隔离插件。这种方法对于性能来说可能更好,但我有点担心,因为插件之间并不是孤立的


这就是我要采用的方法——让每个插件使用相同的
ActorSystem
创建自己的参与者层次结构。每个插件可以有自己的参与者和消息类型,没有重叠。如果您最终运行了多个
ActorSystem
s,您仍然会有多个参与者使用相同的线程,因为默认情况下
ActorSystem
将参与者调度到TPL和桌面应用程序的其他部分可能使用的同一.NET线程池中。让一个
ActorSystem
管理所有这些可能是最简单的,因为这样您就有一个调度器在同一组线程上编组执行(竞争更少)。

我觉得您似乎想得太多了。我不知道AKKA.NET如何适合插件。我们正在考虑转换的插件中都有多个线程触发事件。我们在这里考虑akka的基本原因是,我们对简单线程处理的替代方案看起来像是我们自己实现了一个最小参与者系统。TL;DR:我们在这里使用AKKA的原因是为了简化插件的线程问题,我们不需要自己编写actor系统。好的,另一个问题,为什么插件有多个线程?使用tasks/async/await会更好吗?async/await在某些地方使用,但对于我们的目标插件来说,它并没有那么有用,因为这些代码部分只是处理各种事件源,其中事件来自多个线程。