在类型初始化程序/静态构造函数异常上重新启动IIS AppDomain

时间:2015-06-24 21:26:52

标签: c# asp.net iis asp.net-web-api exception-handling

我有一个依赖于某些使用静态构造函数的代码的ASP.NET。这些类型初始值设定项中的代码有时会失败。让我们说,为了论证,代码是:

public static readonly string Thing = SomeSpecialCallThatRarelyFails();

也许那个卑鄙,但它无法改变。而且这种代码存在于每个控制器中,因此ASP.NET无法创建控制器并且只是在那里被破坏,直到有人来重新启动它。

我理解这是应该的方式,因为问题很可能是非瞬态的,自动重启会产生循环。或者也许只有一个控制器出现故障,因此应用程序仍然存在。所以我得到默认行为只是继续返回错误。但在这种特殊情况下,让我们假装最好的事情是注意到这种失败并重新启动。

如何自动检测此方案并触发重新启动或回收IIS应用程序池/ AppDomain?

我注意到如果我在Application_Start上引起异常,那么应用程序将自动重启。因此,有一种方法可以迭代我的所有类型并尝试访问它们。如果他们有.cctor失败,那么我将崩溃Application_Start并且ASP.NET将重新启动。但这很糟糕,而且如果实际的请求代码引用了另一种我不知道哪种类型会抛出.cctor的类型,它就不会有帮助。

有更好的方法吗?我应该编写Web API过滤器并查找TypeInitializerException或其他内容吗?

2 个答案:

答案 0 :(得分:1)

只是一个想法。是'罕见的失败'确定性?可以通过添加重试逻辑来解决吗?

public static readonly string Thing = RetrySpecialCall();

private static string RetrySpecialCall()
{
    while (true)
    {
        try
        {
            return SomeSpecialCallThatRarelyFails();
        }
        catch (Exception) {}
    }
}

答案 1 :(得分:0)

所以这是在Web API 1中处理它的方法:

在Application_Start中,迭代您的控制器类型,调用System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor以强制运行所有已知类型构造函数。如果Application_Start失败,ASP.NET似乎重新启动。

添加一个查找TypeInitializationExceptions的异常过滤器。然后调用HttpRuntime.UnloadAppDomain()。

这两个部分是必需的,因为无法构造的控制器不会命中异常过滤器。

使用Web API 2,您似乎可以通过实现System.Web.Http.ExceptionHandling.IExceptionLogger并将其注册为全局服务来在one go中执行此操作。相同的逻辑:如果是,请检查TypeInitializationException和UnloadAppDomain。

相关问题