c# Преобразование xslt на большой строке xml приводит к тайм-ауту aspx - PullRequest
0 голосов
/ 08 апреля 2020

Я работаю над старым проектом, используя. NET framework 4.5. Существует страница aspx с событием OnSelectedIndexChanged, которое завершается с помощью вызова на стороне сервера. Вызов на стороне сервера использует сохраненный pro c, который возвращает xml, а затем использует преобразование для преобразования xml в html. Проблема заключается в том, что когда xml большой (в настоящее время выполняется тестирование с 10k записями в формате xml из сохраненного pro c, хотя ожидается, что в работе будет 100k записей), то время ожидания страницы aspx истекает. Я не уверен, что лучший способ решить эту проблему, так как параметры web.config для executeTimeout установлены очень высоко, а для debug установлено значение false.

Web.Config

<httpRuntime maxRequestLength="102400" executionTimeout="20000"/>

ASPX Page

<asp:DropDownList ID="ddlViews" runat="server" AutoPostBack="true" style="height:25px;min-width:150px;"  
    OnSelectedIndexChanged="ddlViews_SelectedIndexChanged">
</asp:DropDownList>

. , .

<asp:UpdatePanel ID="updPnl" runat="server">
    <Triggers> 
        <asp:AsyncPostBackTrigger ControlID="ddlViews" EventName="SelectedIndexChanged" />
     </Triggers>
    <ContentTemplate>
        <asp:Literal ID="litData" runat="server"></asp:Literal>
    </ContentTemplate>
</asp:UpdatePanel>

Код ASPX за

protected void ddlViews_SelectedIndexChanged(object sender, EventArgs e)
{
    if (ddlViews.Items.Count > 0 && ddlViews.SelectedValue != "-1")
    {
        System.Threading.Thread.Sleep(3000);
        ShowView();
    }
}

private void ShowView()
{
    if (ddlViews.Items.Count > 0)
    {
        string inputXml = GetXml();
        strData = Utils.ApplyXslt(inputXml);

        litData.Text = strData;
    }
}

public static string ApplyXslt(string xml)
{
    try
    {
        string xsltUri = GetXslPath();
        XsltArgumentList xslArg = new XsltArgumentList();
        xslArg.AddExtensionObject("urn:string-plus", new XslStringPlus());
        var xdoc = new XmlDocument();
        xdoc.LoadXml(xml);
        var xslt = new System.Xml.Xsl.XslCompiledTransform();

        using (var mStream = new System.IO.MemoryStream())
        {
            xslt.Load(xsltUri);
            xslt.Transform(xdoc, xslArg, mStream);
            mStream.Position = 3;
            var sr = new System.IO.StreamReader(mStream);
            return sr.ReadToEnd();
        }
    }
    catch (Exception e){
        throw new Exception(String.Format("Error Applying Xslt from path '{0}'to xml value '{1}'", xsltUri, xml) + " | " + e.StackTrace);
    }
}

Преобразование занимает около 3 минут, чтобы завершить запись 10k. Было бы здорово иметь возможность резко сократить это время, если это возможно. Страница истекает через 1,5 минуты, и я не могу найти ничего, что могло бы ее увеличить.

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslplus="urn:string-plus">
    <xsl:output method="html" />
    <xsl:template match="/">
        <table  id="tblLoanQuery" class="tableStyle">
            <tr>
                <xsl:for-each select="ROOT/Fields/child::*">
          <xsl:variable name="h" select="." />
                    <th><xsl:value-of select="xslplus:FormatLabel($h)" /></th>
                </xsl:for-each>
            </tr>
            <xsl:for-each select="ROOT/LoanNumbers/child::*">
                <xsl:variable name="loanId" select="." />
                <tr>
                    <xsl:for-each select="//ROOT/Fields/Field">
                        <xsl:variable name="fullFieldName" select="." />
                        <xsl:variable name="field" select="substring-after($fullFieldName,'.')" />
            <xsl:variable name="FieldValue" select="//ROOT/ROWS/row[@lqKey=$loanId]/@*[name(.)= xslplus:ConvertSpace($field)]/." />
            <td>
              <xsl:value-of select="xslplus:FormatValue($FieldValue)"/>              
            </td>
                    </xsl:for-each>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

1 Ответ

1 голос
/ 09 апреля 2020

С точки зрения XSLT кажется, что //ROOT/ROWS/row[@lqKey=$loanId] предполагает, что вы хотите использовать ключ <xsl:key name="row-ref" match="ROOT/ROWS/row" use="@lqKey"/> и использовать key('row-ref', $loanId) вместо //ROOT/ROWS/row[@lqKey=$loanId]. Использование ключа может улучшить производительность во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...