【问题标题】:System.StackOverflowException when using switch case in asp.net在 asp.net 中使用 switch case 时出现 System.StackOverflowException
【发布时间】:2021-03-17 07:02:28
【问题描述】:

我正在用 ASP.NET WebForms 开发一个 Web 应用程序,我正在用 1000 条记录填充一个 gridView 并在 OnRowDataBound 事件中进行一些计算。在 OnRowDataBound 事件中,有一个包含 100 个 switch case 的 switch case,整个 OnRowDataBound 事件函数大约有 13000 行代码。现在,当我运行应用程序以在没有 OnRowDataBound 事件的情况下从服务器获取数据时,它会获取包含 1000 多个记录的所有记录,但是当我尝试使用包含这 100 个开关案例的 OnRowDataBound 事件获取这些记录时,它会进入 System.StackOverFlowException。

作为一种解决方法,我尝试将这些 switch case 减少到 20 个,然后它运行没有任何错误,但当 OnRowDataBound 事件有 100 个 switch case 时会进入异常。

ASPX 页面。

<asp:GridView ID="gvReport" runat="server" CellPadding="4" Font-Names="calibri(body)"
                                            Font-Size="9" ForeColor="#333333" GridLines="Vertical"  OnRowDataBound="gvReport_RowDataBound"
                                            ShowFooter="True" OnRowCreated="gvReport_RowCreated" OnPreRender="gvReport_PreRender"
                                            EmptyDataText="No Data Retrieved">
                                            <AlternatingRowStyle BackColor="White" />
                                            <RowStyle HorizontalAlign="Left" />
                                            <Columns>
                                                <asp:TemplateField>
                                                    <ItemTemplate>
                                                        <asp:CheckBox ID="chk" runat="server" />
                                                    </ItemTemplate>
                                                    <HeaderTemplate>
                                                        <asp:CheckBox ID="chkSelectAll" runat="server" onclick="checkAll(this);" />
                                                    </HeaderTemplate>
                                                </asp:TemplateField>
                                                <asp:TemplateField HeaderText="No">
                                                    <ItemTemplate>
                                                        <%#Container.DataItemIndex+1 %>
                                                    </ItemTemplate>
                                                </asp:TemplateField>
                                            </Columns>
                                            <EditRowStyle BackColor="#2461BF" />
                                            <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
                                            <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" CssClass="Freezing"
                                                Wrap="True" HorizontalAlign="Left" VerticalAlign="Middle" BorderColor="#505050"
                                                BorderStyle="Solid" BorderWidth="1" />
                                            <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
                                            <RowStyle BackColor="#EFF3FB" />
                                            <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
                                            <SortedAscendingCellStyle BackColor="#F5F7FB" />
                                            <SortedAscendingHeaderStyle BackColor="#6D95E1" />
                                            <SortedDescendingCellStyle BackColor="#E9EBEF" />
                                            <SortedDescendingHeaderStyle BackColor="#4870BE" />
                                            <SortedAscendingCellStyle BackColor="#F5F7FB" />
                                            <SortedAscendingHeaderStyle BackColor="#6D95E1" />
                                            <SortedDescendingCellStyle BackColor="#E9EBEF" />
                                            <SortedDescendingHeaderStyle BackColor="#4870BE" />
                                        </asp:GridView>

ASPX.cs 页面

protected void gvReport_RowDataBound(object sender, GridViewRowEventArgs e)
    { 
switch(Condition){
            case"":{
                   try
                {
                    if (e.Row.RowType == DataControlRowType.DataRow)
                    {
                        try
                        {
                            strPrevious = DataBinder.Eval(e.Row.DataItem, "Territory").ToString();

                        }
                        catch (Exception ex)
                        {

                        }
                        dblSubTotal += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Retailer code").ToString());
                        dblTotal += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Retailer code").ToString());

                        dblSubTotal2 += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Retailer mapped").ToString());
                        dblTotal2 += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Retailer mapped").ToString());
                    }
                }////////////// Such types of calculations are there in 100's of switch cases.
                catch (Exception ex)
                {

                }
                 }
           break; /////////// there are 100's of cases in switch statement, if reduced to 15-20 cases 
         then runs without any exception. 
        }
    }

这是 OnRowDataBound 事件产生的异常。

【问题讨论】:

  • 导致这些问题的可能不是案例数量,而是具体案例。说了这么多,我们在这里所能做的就是猜测你没有在问题中发布的那个丢失的案例。顺便说一句:case "" { } break 看起来很奇怪,我想知道它是否还能编译。
  • switch (Condition="") 会编译。但是它在布尔值上执行开关,而不是在字符串上。你可能想要switch(Condition) { case "": { ...; break; } }
  • 如果没有您的实际代码,几乎不可能为您提供帮助。您绝对应该提供Minimal, Reproducible Example。我们只能猜测前面提到的编译器错误是否与您的问题有关,或者您的实际问题是否属于您未发布的任何情况。
  • @HimBromBeere 我已经更正了开关条件。
  • 使用二分切策略(删除一半的案例,如果出现问题,则删除剩余的一半,如果没有出现问题,则添加一半已删除的案例,重复)找到导致问题的案例并发布在这里进入你的问题。也许它调用 gvReport_RowDataBound 或其他东西,进而导致它被再次调用(如数据绑定?)。您还可以使用调试器单步执行并观察触发了哪些案例,以及为什么代码会循环使用相同的方法,直到它崩溃

标签: c# asp.net webforms


【解决方案1】:

我会采用的最简单的方法是二分法,(拆分您的switch cases,直到找到有罪的人)。您至少有一个(可能更多)switch case 正在触发相同的事件 (OnRowDataBound)。 我知道有很多情况,但这可能是获得结果的最有效方法。一旦找到嫌疑人,您必须打破(断点)并逐步执行,直到找到触发事件并因此触发递归的行。 还有一个好方法是在gvReport_RowDataBound的入口处添加一个断点,然后一旦你中断,你做几个F5继续并构建Call Stack的一部分,然后看看调用堆栈窗口(Windows>Call Stack),双击调用堆栈的每一行将带您到代码中触发它的行,您可以在此处查看触发递归的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    相关资源
    最近更新 更多