IIS6应用程序池崩溃

时间:2011-09-16 01:20:29

标签: c# asp.net exception-handling try-catch

在最近的压力和体积测试中,我们意识到在30分钟后,所有用途都与网站断开连接。在事件记录之后,我们注意到应用程序池崩溃了。做一些谷歌调查,显然在大多数情况下这是由于未处理的例外。

因此,当应用程序崩溃时,会显示以下异常详细信息:

An unhandled exception occurred and the process was terminated.

Application ID: DefaultDomain

Process ID: 7852

Exception: System.Runtime.Serialization.SerializationException

Message: Type 'FuseFarm.FrameworkException' in Assembly 'FuseFarm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

StackTrace:    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
   at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
   at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeObject(Object obj, MemoryStream stm)
   at System.AppDomain.Serialize(Object o)
   at System.AppDomain.MarshalObject(Object o)

我不知道它为什么要尝试序列化FrameworkException,我也无法在代码中看到这样做。但我确实看到了代码的几个部分

new FrameworkException(exData, "ContractComposition.SubmitContract");
正在调用

,但没有被处理。检查global.asax.cs后,发生以下情况:

protected void Application_Error(object sender, EventArgs e)
{
    ILog log = LogManager.GetLogger(typeof(Global));
    string environmentName = WebConfigurationManager.AppSettings["EnvironmentName"];
    if (!String.IsNullOrEmpty(environmentName) && (environmentName == "DEMO" || environmentName == "LIVE"))
    {
        Exception currentException = Server.GetLastError().GetBaseException();
        Session["errorMessage"] = currentException.Message;
        Session["errorSource"] = currentException.Source;
        Session["errorTrace"] = currentException.StackTrace;
        log.Error(currentException.Message, currentException);
        if (currentException != null)
        {
            Session["error"] = currentException.GetType().Name;
            switch (currentException.GetType().ToString())
            {
                case "System.ApplicationException":
                case "FuseFarm.FrameworkException":
                    break;
                default:
                    new FrameworkException(currentException.Message + "\n" + currentException.StackTrace, currentException.Source, currentException);
                    break;
            }

        }
        Server.Transfer("~/error.aspx");
    }
}

在Application_Error中抛出一个新的异常......这似乎不正确?如果此时出现错误,谁和什么会处理此错误?

2 个答案:

答案 0 :(得分:3)

它正在序列化FrameworkException,因为它正试图跨越AppDomain边界。

必须序列化遍历AppDomain的所有对象,并且异常也不例外。

当异常未正确实现序列化时,您可以consider it a bug

我不相信你的错误处理程序是问题的根源。给定堆栈跟踪很难说 - 完整的内存转储会产生更好的信息。

最好的办法是properly make the exception serializable

这可能无法完全解决您的问题 - 归结为,您仍然会抛出异常。希望一旦纠正,您将看到问题的真正原因。

答案 1 :(得分:0)

如果在Application_Error中抛出异常,您的应用程序池将崩溃,就像您所看到的那样。 根据您显示的代码,我会得出结论:行中引用的错误记录器:

log.Error(currentException.Message, currentException);

正在尝试序列化传递给它的异常。当currentException最终属于FuseFarm.FrameworkException类型时,错误处理程序会在该行崩溃并且您的应用程序池关闭。

如果是这种情况,您需要将FuseFarm.FrameworkException标记为Serializable,将记录器更改为不尝试序列化对象,或者在{{1}中放置try / catch块如果您希望应用程序池继续运行,请使用处理程序并对这些异常执行其他操作。