为什么这段代码不仅让页面无法显示,还会导致我的电脑不稳定?
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 "New" to "Existing" (uncheck any that should remain "New")</asp:TextBox>
</div>
<asp:Panel ID="Panel1" runat="server" Height="582px">
</asp:Panel>
<asp:Button ID="Button1" runat="server" Text="Update checked to "Existing"" 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
我在 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 "New" to "Existing" (uncheck any that should remain "New")</asp:TextBox>
</div>
<asp:Panel ID="Panel1" runat="server" Height="582px">
</asp:Panel>
<asp:Button ID="Button1" runat="server" Text="Update checked to "Existing"" 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