为什么这段代码不仅让页面无法显示,还会导致我的电脑不稳定?

Why does this code not only prevent the page from displaying, but also causes my computer to become unstable?

我在 ASP.NET WebForms 应用程序中有代码,在 Page_Load 处理程序中,它不仅不执行我想要它执行的操作(现在,显示一堆带有相应标签的复选框,简单地说 "something") 但也会导致页面不显示,甚至导致鼠标无响应,直到我终止浏览器实例并随机打开 windows启动 - Windows Explorer,然后是 Visual Studio Server Explorer(我已经有一段时间没有打开了)。

当我打开事件代码被注释掉的页面时,页面会显示,但即​​便如此(这可能是一个线索,我不知道)当我混合 F12 时,控制台选项卡显示,"The attached page targets document mode 7. Some console APIs and features may not be available." 相同的消息出现在“调试器”选项卡的顶部。

我不知道那 "document mode 7" 东西是无害的还是很奇怪,或者是什么。

这是一段似乎在造成严重破坏的代码;这是整个 .aspx.vb 文件的内容:

Imports System.Data
Imports DAL05.DataAccess

Partial Class pages_custmaint_categoryadmin
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles Me.Load
        Dim sqlDAL As New SQLServer(ConfigurationSettings.AppSettings("ConnectionString"))
        Dim sql As String
        Dim retDS As DataSet
        Dim categoryDT As DataTable
        sql = "select C.CompanyName from CustomerCategoryLog CCL join Customers C on C.CustNo = CCL.Custno where CCL.Category = 'New' and C.Active <> 0 order by C.CompanyName"
        retDS = sqlDAL.runSQLDataSet(sql)
        categoryDT = retDS.Tables(0)
        'CategoryDDL.DataSource = categoryDT
        'CategoryDDL.DataTextField = "Category"
        'CategoryDDL.DataBind()

        For i As Integer = 0 To categoryDT.Rows.Count
            For j As Integer = 0 To categoryDT.Rows.Count
                Dim coName = New Label()
                coName.Text = "something" 'categoryDT.Rows[i].ToString()
                formCustCatMaint.Controls.Add(coName)
                Dim chk = New CheckBox()
                chk.ID = "chk." + i.ToString() + "." + j.ToString()
                formCustCatMaint.Controls.Add(chk)
            Next
            Dim l = New Label()
            l.Text = "<br>"
            formCustCatMaint.Controls.Add(l)
        Next

        sqlDAL.Dispose()

    End Sub
End Class

对应的.aspx页面就是这样:

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="custmaint_categoryadmin.aspx.vb" Inherits="pages_custmaint_categoryadmin" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Customer Category Maintenance</title>
</head>
<body>
    <form id="formCustCatMaint" runat="server">
    <div>

        <asp:TextBox ID="TextBox1" runat="server" Width="675px">Move the following from &quot;New&quot; to &quot;Existing&quot; (uncheck any that should remain &quot;New&quot;)</asp:TextBox>

    </div>
        <asp:Panel ID="Panel1" runat="server" Height="582px">
        </asp:Panel>
        <asp:Button ID="Button1" runat="server" Text="Update checked to &quot;Existing&quot;" Width="216px" />
    </form>
</body>
</html>

如果 Page_Load 事件中的所有代码都被注释掉,则没有异常行为("mode 7" 消息除外)。上面的代码中有什么可能导致这种混乱?

我从公认的解决方案 here and ran it through Telerik's C# to VB.NET converter here 中获得了这个基本代码 - 动态创建复选框,因此根据我的需要对其进行了调整,如上所示。

查询返回了很多行(数千行),但我认为还不足以导致这种问题。

更新

事件被触发,因为在注释掉所有其他代码后,我添加了这个来测试它:

TextBox1.Text = "whatever"

...并且有效 - TextBox1 的文本更改为 "whatever"

所以查询代码有问题。不过,什么?

更新 2

我将尝试用小步骤来测试它;我将代码缩减为:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim sqlDAL As New SQLServer(ConfigurationSettings.AppSettings("ConnectionString"))
    Dim sql As String
    Dim retDS As DataSet
    Dim categoryDT As DataTable
    sql = "select distinct CompanyName from Customers"
    retDS = sqlDAL.runSQLDataSet(sql)
    categoryDT = retDS.Tables(0)

    sqlDAL.Dispose()

End Sub

...页面加载;当然,它没有显示任何数据,但我会继续添加它以查看故障发生的位置。查询是否太复杂?问题出在循环逻辑上吗?或者 what/where?

更新 3

接下来,在对 DataTable 的赋值和 sqlDAL.Dispose 之间,我添加了这个:

For i As Integer = 0 To 5 'categoryDT.Rows.Count
    For j As Integer = 0 To 3 'categoryDT.Rows.Count
        Dim coName = New Label()
        coName.Text = "something" 'categoryDT.Rows[i].ToString()
        formCustCatMaint.Controls.Add(coName)
        Dim chk = New CheckBox()
        chk.AutoPostBack = True
        chk.ID = "chk." + i.ToString() + "." + j.ToString()
        formCustCatMaint.Controls.Add(chk)
    Next
    Dim l = New Label()
    l.Text = "<br>"
    formCustCatMaint.Controls.Add(l)
Next

...与以前一样,但使用硬编码的小值而不是 DataTable 行计数作为循环限制。

有点效果,有点像:

不可否认,这是一种丑陋的时尚,但它帮助我看到问题一定出在 categoryDT.Rows.Count...

所以我恢复了真实的查询字符串,注释掉了测试字符串,并添加了这个:

TextBox1.Text = categoryDT.Rows.Count.ToString()

...看到值为 26,821。也许这就是问题所在——要处理的数据太多了……复选框太多了……

更新 4

结果集只有一列,因为它只有 returns 一个值,所以我可以将循环代码简化为:

For i As Integer = 0 To categoryDT.Rows.Count
    Dim coName = New Label()
    coName.Text = "something"
    formCustCatMaint.Controls.Add(coName)
    Dim chk = New CheckBox()
    chk.ID = "chk." + i.ToString() '+ "." + i.ToString()
    formCustCatMaint.Controls.Add(chk)
Next

当然,"something" 因为每个复选框的标签都不够准确;下一个挑战是找出如何从结果 set/table 中获取值。 categoryDT.Rows[i] 不是吗; categoryDT.Rows[i] As String 不是...

更新 5

我尝试使用此代码从 table:

中获取结果
    For i As Integer = 0 To categoryDT.Rows.Count-1
        Dim coName = New Label()
        categoryDT.Rows(i).ToString()
        formCustCatMaint.Controls.Add(coName)
        Dim chk = New CheckBox()
        chk.ID = "chk." + i.ToString() '+ "." + i.ToString()
        formCustCatMaint.Controls.Add(chk)
    Next

...但我只得到具有相同标签 ("System.Data.DataRow") 的 beaucoup 复选框。

在你的循环中,你写了两次行。如果您有 1000 行,这将导致创建 100 万个控件。这可能是问题所在。

下面我更改了第二个循环以遍历列。

此外,您可能需要如下更改 coName.Text。

For i As Integer = 0 To categoryDT.Rows.Count - 1
        For j As Integer = 0 To categoryDT.Columns.Count - 1
            Dim coName = New Label()
            coName.Text = categoryDT.Rows(i)(j).ToString()
            formCustCatMaint.Controls.Add(coName)
            Dim chk = New CheckBox()
            chk.ID = "chk." + i.ToString() + "." + j.ToString()
            formCustCatMaint.Controls.Add(chk)
        Next
        Dim l = New Label()
        l.Text = "<br>"
        formCustCatMaint.Controls.Add(l)
    Next

对于完整的解决方案,以下是代码需要的内容,利用 fofik 的指导,在页面上获得我需要的内容,并默认选中所有复选框:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim sqlDAL As New SQLServer(ConfigurationSettings.AppSettings("ConnectionString"))
    Dim sql As String
    Dim retDS As DataSet
    Dim categoryDT As DataTable
    sql = "select C.CompanyName from CustomerCategoryLog CCL join Customers C on C.CustNo = CCL.Custno where CCL.Category = 'New' and C.Active <> 0 order by C.CompanyName"
    retDS = sqlDAL.runSQLDataSet(sql)
    categoryDT = retDS.Tables(0)

    For i As Integer = 0 To categoryDT.Rows.Count-1
        Dim coName = New Label()
        coName.Text = categoryDT.Rows(i)(0).ToString()
        formCustCatMaint.Controls.Add(coName)
        Dim chk = New CheckBox()
        chk.ID = "chk." + i.ToString()
        chk.Checked = True
        formCustCatMaint.Controls.Add(chk)
        ' Add a "line break" after each checkbox
        Dim l = New Label()
        l.Text = "<br>"
        formCustCatMaint.Controls.Add(l)
    Next

    sqlDAL.Dispose()
End Sub