2

我有一个用户控件,大部分时间可以正常处理数千个请求,但通常每天大约一次或两次,有一个 ArgumentOutOfRangeException 指向 aspx.vb 的代码隐藏中的 Page_Load 方法的第一行文件。我自己从未能够复制它,但我记录了错误的详细信息/堆栈跟踪。问题是,我很肯定 Page_Load 块中实际上并没有发生错误,尽管堆栈跟踪表明并非如此。事实上,我在那里有什么代码并不重要,为了证明这一点,我在 Page_Load 中放了一些虚拟代码,发布并等待下一次出现如下......

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim abc As Integer = 123
        abc = abc + 1
        ...
    End Sub

果然,当错误最终再次发生时,它仍然指向 Page_Load 的第一行(第 16 行:Dim abc As Integer = 123)。显然,这不是会生成 ArgumentOutOfRangeException 的语句类型。

Type: System.ArgumentOutOfRangeException
Message: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source: mscorlib
TargetSite: Void ThrowArgumentOutOfRangeException()
StackTrace:    at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at aut.ProductWithColorChoice.Page_Load(Object sender, EventArgs e) in F:\Visual Studio Projects\1003\templates\usercontrols\ProductWithColorChoice.ascx.vb:line 16
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

.ascx 页面上使用的唯一内联代码实际上是在 javascript 块中找到的,用于获取控件的 ClientId,以在页面完全加载之前禁用控件。

<%@ Control Language="vb" AutoEventWireup="false" Inherits="aut.ProductWithColorChoice" %>
<script language="javascript" type="text/javascript">
(function () {
    Sys.Application.add_load(setupButtonDisablers);
    function setupButtonDisablers() {
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(onPageLoad);
        Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onSubmit);
        Sys.Application.remove_load(setupButtonDisablers);
    }
    function onPageLoad() {
        findAndEnable('<%= AddToCartImageButton.ClientID %>');
    }
    function onSubmit() {
        findAndDisable('<%= YearDropDownList.ClientID %>');
        findAndDisable('<%= MakeDropDownList.ClientID %>');
        findAndDisable('<%= ModelDropDownList.ClientID %>');
        findAndDisable('<%= ColorDropDownList.ClientID %>');
        findAndDisable('<%= AddToCartImageButton.ClientID %>');
    }
    function findAndDisable(id) { findAndSetDisabledProperty(id, true); }
    function findAndEnable(id) { findAndSetDisabledProperty(id, false); }
    function findAndSetDisabledProperty(id, value) {
        var control = $get(id);
        if (control) control.disabled = value;
        else alert('could not find ' + id);
    }
})();
</script>

我通过记录收集到,此错误总是发生在可能通过数据绑定下拉列表的自动回发事件触发的回发上。

另一件要提到的事情是,该控件继承了另一个名为 ProductControlBase 的类,该类随后继承了 UserControl。但是,我认为,如果错误确实发生在那里,堆栈跟踪将表明这一点。

很长一段时间以来,我一直被这个问题所困扰,并且希望对可能导致该异常的原因有所了解,或者对如何获取有关该问题的更多调试信息的一些建议(尽管我无法直接复制它)。

2012 年 12 月 7 日更新 我还没有解决它,但已经取得了进展。发现堆栈跟踪没有指向代码中的正确行,可能是由于编译器优化,错误可能是这个块中的几行......考虑到 if 语句中的检查,你能看到任何可能性吗sizeIndex 不会在 0 - 6 的范围内?注意:PaintSizes、RegularPaintPrices 和 PaintWeights 都是 Specialized.StringCollections,每个都有 7 个字符串。

    If My.Settings.PaintSizes.Contains(SizeOption) Then
        sizeIndex = My.Settings.PaintSizes.IndexOf(SizeOption)            
        Price = Decimal.Parse(My.Settings.RegularPaintPrices(sizeIndex))
        Weight = Double.Parse(My.Settings.PaintWeights(sizeIndex))
    Else
        Throw New ApplicationException(Me.ID & ": sizeoption must match exactly one of the values in PaintSizes located in the web.config file")
    End If
4

0 回答 0