对类型初始值设定项/静态构造函数异常重新启动IIS AppDomain

本文关键字:构造函数 静态 异常 重新启动 AppDomain IIS 类型 | 更新日期: 2023-09-27 17:59:26

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

public static readonly string Thing = SomeSpecialCallThatRarelyFails();

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

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

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

我注意到,如果我在Application_Start上引发异常,那么应用程序将自动重新启动。因此,一种方法是对我的所有类型进行迭代,并尝试访问它们。如果他们有.ctor故障,那么我将使Application_Start和ASP崩溃。NET将重新启动。但这很麻烦,而且如果实际的请求代码引用了另一种类型,而我不知道它会在.cctor.上抛出,那也无济于事

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

对类型初始值设定项/静态构造函数异常重新启动IIS AppDomain

只是一个想法。"罕见故障"是否具有确定性?可以通过添加重试逻辑来解决吗?

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

因此,这里有一种在Web API 1:中处理它的方法

在Application_Start中,迭代控制器类型,调用System。运行时。编译器服务。RuntimeHelpers。RunClassConstructor强制运行所有已知的类型构造函数。如果Application_Start失败,ASP。NET似乎要重新启动了。

添加一个异常筛选器,用于查找TypeInitializationExceptions。然后调用HttpRuntime。卸载AppDomain()。

这两个部分是必需的,因为构造失败的控制器不会碰到异常过滤器。

使用Web API 2,您似乎可以通过实现System一次性完成。网状物Http。例外处理。IExceptionLogger并将其注册为全局服务。相同的逻辑:如果是,则检查TypeInitializationException和UnloadAppDomain。