You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET代码无法捕获System.Xml.Xsl.XslLoadException致IIS崩溃

无法捕获XslCompiledTransform加载错误XSLT时抛出的XslLoadException异常

加载存在错误的XSLT样式表时,即便用try { } catch(Exception unhandled) { }包裹代码,也无法捕获XslCompiledTransform抛出的异常,最终导致w3wp.exe崩溃。当前场景是引用的样式表存在重复模板函数,需要明确为何C#代码处理不了System.Xml.Xsl.XslLoadException异常。

调试获取的错误信息

System.Xml.Xsl.XslLoadException
  HResult=0x80131942
  Message='helper.name' is a duplicate template name.
  Source=FLX
  StackTrace:
   at ProjectFlx.FlxTemplater.LoadTransformation(XslCompiledTransform xslt) in D:\GitHub\ProjFlx\Src\TMPLTSite\WebTemplater.cs:line 475
   at ProjectFlx.FlxTemplater.<>c__DisplayClass38_0.<ProcessTemplate>b__0() in D:\GitHub\ProjFlx\Src\TMPLTSite\WebTemplater.cs:line 429
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

  This exception was originally thrown at this call stack:
    [External Code]
    ProjectFlx.FlxTemplater.LoadTransformation(System.Xml.Xsl.XslCompiledTransform) in WebTemplater.cs
    ProjectFlx.FlxTemplater.ProcessTemplate.AnonymousMethod__0() in WebTemplater.cs
    [External Code]

调用代码

注:因XML和XSL复杂度高、体积大,需要增大转换栈大小,所以用了线程匿名调用。

try
{
    var xslt = new XslCompiledTransform();
    //xslt = LoadTransformation(xslt);
    System.Threading.Thread t = new System.Threading.Thread(() => xslt = LoadTransformation(xslt), 8 * 1024 * 1024);
    t.Start();
    t.Join();

    XsltArgumentList xsltparms = DicToXsltParms();
    using (var mem = new MemoryStream())
    {
        _xml.Save(mem);
        mem.Flush();
        mem.Seek(0, SeekOrigin.Begin);

        var readersettings = new XmlReaderSettings();
        var reader = XmlReader.Create(mem, readersettings);

        using (_writer = new StringWriter())
        {
            xslt.Transform(reader, xsltparms, _writer);
        }
    }
}
catch(System.Xml.Xsl.XsltCompileException handled)
{
    System.Diagnostics.Debug.WriteLine("Caught XsltCompileException");
    System.Diagnostics.Debug.WriteLine(handled.Message);
}
//catch(System.Xml.Xsl.XslLoadException handled)
//{

//}
catch (Exception unhandled)
{
    var ex = new Exception("Failed to Transform xml/xslt", unhandled);
    ex.Source = "ProjectFlx.FlxTemplater.ProcessTemplate";
    throw ex;
}

问题原因及解决方案

核心原因

异常在新建的子线程中抛出,外层try/catch仅能捕获当前主线程的异常,无法捕获子线程的未处理异常。子线程的执行上下文独立于主线程,未处理异常会直接导致进程崩溃。

修复方案

  1. 将异常捕获逻辑移到子线程内部,确保捕获子线程中LoadTransformation抛出的异常:
// 定义共享变量存储异常信息
private Exception _loadException;

// 修改线程创建逻辑
System.Threading.Thread t = new System.Threading.Thread(() => 
{
    try
    {
        xslt = LoadTransformation(xslt);
    }
    catch(XslLoadException ex)
    {
        System.Diagnostics.Debug.WriteLine($"XSL加载失败:{ex.Message}");
        _loadException = ex;
    }
    catch(Exception ex)
    {
        System.Diagnostics.Debug.WriteLine($"线程执行异常:{ex.Message}");
        _loadException = ex;
    }
}, 8 * 1024 * 1024);
  1. 主线程等待子线程结束后检查异常状态,根据结果决定后续流程:
t.Start();
t.Join();

// 检查子线程是否抛出异常
if(_loadException != null)
{
    throw new Exception("XSL样式表加载失败", _loadException);
}

// 后续转换逻辑继续执行...
  1. 启用XslLoadException的捕获分支,在主线程中针对性处理该异常类型,避免遗漏:
catch(System.Xml.Xsl.XslLoadException handled)
{
    System.Diagnostics.Debug.WriteLine("Caught XslLoadException");
    System.Diagnostics.Debug.WriteLine(handled.Message);
    // 这里可以添加友好提示、日志记录等逻辑
}

内容的提问来源于stack exchange,提问作者kstubs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:25:40