AppDomains与强大的服务器

经过一些研究后,AppDomains似乎并不是构建托管服务器的真正工具。 根据我的理解,如果在创建的AppDomain中存在未处理的exception(如果从创建的AppDomain中的线程抛出exception),托管服务器仍将崩溃。 因此,在这种情况下,如果托管服务器托管泄漏exception的服务,这也将导致默认的AppDomain失效。

所以我想从服务器架构的角度来看,没有比创建子进程和监视它们更好的了。

这是正确的还是我错过了AppDomains的东西?

谢谢,克里斯托夫

如果可以控制在其他AppDomain中创建的线程,则还可以通过在线程main方法中使用catch-all块来处理exception。

除此之外,只要您使用默认主机,我相信您的假设是正确的。 但是,如果您自己托管运行时,还可以处理未处理的exception。

来自关于该主题的论坛post :

嗯,这是可能的。 您必须创建自己的CLR主机。 这从ICorBindToRuntimeEx()开始。 您可以完全控制引发exception的AppDomains。 它正在被ASP.NET和SQL Server 2005等MSFT软件使用。当您编写服务时,您正在使用默认的CLR主机实现,它会在引发任何未处理的exception时终止该进程,无论AppDomain导致exception是什么。

问题是,像ASP.NET和SQL服务器这样的主机有一个非常明确的代码执行路径。 在Web服务器中,托管代码由于页面请求而运行。 在dbase服务器中,它由于查询而运行。 当一些不好的事情发生时,他们可以简单地中止请求开始的一切(杀死AppDomain)并将“抱歉,无法做到”状态返回给客户端。 您可能已经看过它,在旧网站上崩溃论坛服务器非常简单,但并没有阻止它提供其他请求。 实际上并非100%确定。

您的服务实现可能不是那么干净。 我不知道,你没有说什么。 一般来说,中止线程有问题。 当存在未处理的exception时,您总是必须中止一个线程。 服务通常有一个线程,由OnStart()方法启动。 中止它会杀死服务器,直到有人停下来再次启动它。

你绝对可以使它更具弹性,你可以启动一个“主”线程来启动子线程,以响应使你的服务完成工作的外部事件。 由于未处理的exception导致子线程终止是您可以从中恢复的。 但是,如果您进行下一步,为什么不让子线程捕获exception并将其传递回主线程,以便它可以明智地决定下一步该做什么。

默认CLR主机的冷酷事实是:如果您不愿意处理失败,那么它就不会为您完成任务。 并且它不应该,.NET 1.x行为导致死机exception死亡是一个在.NET 2.0中得到纠正的重大错误。

你知道该怎么做:处理失败。 或者写你自己的主人。 或接受事情可能超出您的控制并记录一条好的错误消息,以便您可以告诉您的客户该做什么。 我强烈推荐后者。