【问题标题】:Restart IIS AppDomain on type initializer/static constructor exception在类型初始化程序/静态构造函数异常上重新启动 IIS AppDomain
【发布时间】:2015-09-11 07:03:20
【问题描述】:

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

public static readonly string Thing = SomeSpecialCallThatRarelyFails();

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

我知道这是应该的方式,因为问题很可能是非暂时性的,并且自动重启会创建一个循环。或者也许只有一个控制器出现故障,所以该应用程序仍然存在。所以我得到默认行为只是继续返回错误。但在这种特殊情况下,让我们假设最好的办法是注意到此故障并重新启动。

如何自动检测这种情况并触发 IIS 应用程序池/AppDomain 的重新启动或回收?

我注意到,如果我在 Application_Start 上引发异常,则应用程序将自动重新启动。因此,一种方法是让我遍历所有类型并尝试访问它们。如果他们有 .cctor 失败,那么我将崩溃 Application_Start 并且 ASP.NET 将重新启动。但这很 hacky,而且如果实际的请求代码引用了另一种我不知道会在 .cctor 上引发的类型,它也无济于事。

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 我想避免修改任何客户端代码,而是通过对 ASP.NET/Web API 进行全局处理来解决它。
    【解决方案2】:

    所以这里有一种在 Web API 1 中处理它的方法:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 2011-02-15
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多