13

我在 ASP.NET 中创建了一个带有 RESTful API 的服务,托管在 IIS 中。在这个服务中,我想用 Akka.NET 创建一个演员系统。

创建演员系统后:

var actorSystem = ActorSystem.Create("myActorSystem");

抛出以下异常:

System.Web.dll 中出现“System.InvalidOperationException”类型的第一次机会异常附加信息:此时无法启动异步操作。异步操作只能在异步处理程序或模块内或在页面生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保将页面标记为 <%@ Page Async="true" %>。此异常还可能表示尝试调用“async void”方法,在 ASP.NET 请求处理中通常不支持该方法。相反,异步方法应该返回一个任务,调用者应该等待它。

Actor 系统本质上是一个并发系统,在 Actor 之间交换异步消息。正如这里所解释的,这个actor系统将无法在 IIS 关闭 AppDomain 后继续存在,这可能就是引发上述异常的原因。

本文介绍了如何在 ASP.NET 中运行后台任务。但是,我不知道如何将它用于我的演员系统,因为我无法控制可能由 Akka.NET 创建的后台任务的生命周期。

有没有办法使这项工作,或者我应该放弃在 ASP.NET 应用程序中拥有演员系统的想法?

编辑:我还在 Stackoverflow 上看到了一个关于使用 Akka 实现 REST 服务的问题。欢迎任何关于类似于Spray 工具包但适用于 Akka.NET 的解决方案的建议。

4

2 回答 2

26

我在 ASP.NET MVC 应用程序中使用了 Akka.NET 和 Akka.Remote,它们在 EC2 上每秒执行多达 1000 个请求 - 所以我将分享一些我用来成功启动和运行它的技巧和窍门。有一个原型版本,它甚至使用了 Akka.Cluster,但最终没有发布该版本。

  • 最好的通话地点ActorSystem.Create是 Global.asax 内Application_Start()
  • ActorSystem使用静态字段或属性,对 Global.asax 本身内部的对象进行静态引用。有助于确保其ActorSystem本身不会在长时间运行的应用程序中被垃圾收集。
  • 创建一个单独的静态帮助器类来初始化您的应用程序需要的任何顶级参与者 - 即/user/层次结构顶部的参与者。此类还应提供您的 ASP.MVC 控制器和操作方法可用于TellAsk操作的参与者路径。

创建它ActorSystem是一项昂贵的操作,因为很多系统级的东西会立即启动。最好在应用程序启动时执行一次,然后将结果缓存在Application类中。

创建单独的actor实例很便宜——您应该能够在 ASP.NET MVC 操作方法中毫无问题地做到这一点。如果您再次看到此错误,请让我们知道此错误发生在请求处理过程的哪个部分以及哪个版本的 ASP.NET。

于 2014-12-25T08:12:13.360 回答
22

将您的 ActorSystem 作为共享属性保存在某个静态类容器中 - 这样您就可以从应用程序的其余部分访问它。Actor 系统初始化/处置可以通过以下方式完成:

  • Global.asax -ActorSystem.Create(...)在 Global.asax中使用并使用onApplication_Start处理它。system.Shutdown()Application_End
  • OWIN - 在 OWIN 的方法中创建参与者系统并通过绑定到host.OnAppDisposing事件(操作方法链接Startup.Configuration)将其关闭。

请记住,IIS 只会在第一次请求后启动您的 Web 应用程序,并在它空闲一段时间后自动将其关闭。因此,如果您希望 Akka 演员系统持续运行,请确保您的部署脚本将在发布后 ping 应用程序并设置空闲超时(链接)足够长的时间。

第二种选择

分离您的 Actor 系统逻辑并将其部署为例如 Windows 服务(或 Linux 守护程序)。为它打开 Akka.Remoting 并创建一个代理客户端,它将所有应用程序长时间运行的敏感任务转发给外部服务。当您的应用程序逻辑必须连续工作时,类似的解决方案通常用于调度程序或事件总线等事物。

于 2014-12-31T10:34:45.960 回答