ASP.NET中的Akka.NET actor系统

时间:2014-12-24 09:47:01

标签: asp.net spray hangfire akka.net

我在ASP.NET中使用RESTful API创建了一个服务,该服务托管在IIS中。在这个服务中,我想用Akka.NET创建一个actor系统。

创建演员系统后:

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

抛出以下异常:

  

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

actor系统本质上是一个并发系统,在actor之间交换异步消息。正如here所解释的那样,这个actor系统无法在IIS中取消AppDomain,这可能就是为什么抛出上述异常的原因。

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

有没有办法让这项工作成功,还是应该放弃在ASP.NET应用程序中使用actor系统的想法?

编辑:我还在Stackoverflow上看到了一个关于implementing a REST service using Akka的问题。关于类似于Spray toolkit的解决方案的任何建议,但欢迎为Akka.NET工作。

2 个答案:

答案 0 :(得分:25)

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

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

创建ActorSystem是一项非常昂贵的操作,因为很多系统级的东西会立刻被激活。在应用程序启动时,最好这样做一次,然后将结果缓存在Application类中。

创建单个actor实例很便宜 - 您应该能够在ASP.NET MVC操作方法中执行此无问题。如果您再次看到此错误,请告诉我们发生此错误的请求处理过程中的哪个部分以及ASP.NET的版本。

答案 1 :(得分:22)

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

  • Global.asax - 在Global.asax ActorSystem.Create(...)中使用Application_Start,并在system.Shutdown()上使用Application_End进行处理。
  • OWIN - 在OWIN的Startup.Configuration方法中创建actor系统,并通过绑定到 host.OnAppDisposing 事件(how-to link)将其关闭。< / LI>

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

第二个选项

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