我有一个 Event
,当 TextBox
文本在 c#.net 中更改时启动。
Event
遍历 GridView
行。 GridView
是使用数据库中的信息创建的。此 GridView
有八个 TemplateFields
,其中七个带有 TextBox
控件,一个带有 DropDownList
控件。
问题是这个事件耗时 26 到 27 秒。
对于每一行,它应该:
- 检查 [4] 列内容是否等于“BATCH”,如果为真,则绘制 整行用不同的颜色。
- 从 [0] 列中提取 ID。
- 使用此 ID 和
TextBox
中的日期进行查询 如果记录已经存在于数据库中。 - 如果记录存在,它应该将其打印到
TemplateField
的TextBox
和DropDownList
中。 - 如果数据库中的某些记录为空,则有一些
TextBox
不应打印它。
附加信息:
GridView
是使用数据库中的数据创建的,使用QUERY
在SqlDataSource
中。这发生在同一事件中。这QUERY
包含一些INNER JOIN
,数据不存储在 相同的数据库表:SELECT Dealer.IDDealer,Batch.IDBatch,Lpars.Nombre,Dealer.DealerCodigo,Batch.Nombre AS Expr1,Batch.CTStart AS Expr2 FROM Lpars INNER JOIN Dealer ON Lpars.IDLpar = Dealer.IDLpar INNER JOIN Batch ON Dealer.IDDealer = Batch.IDDealer INNER JOIN [1Monday] ON Batch.IDBatch = [1Monday].IDBatch WHERE (Batch.Status = 'Enabled') ORDER BY Batch.CTStart
响应时间问题不是因为顶部的
SQL QUERY
。我尝试过这个 分开并且此查询的 SQL Server 响应时间更少 不到 2 秒。- 我从数据库中提取了一些
DATETIME
数据。所以,之前 我将它打印到TextBox
中,我需要更改DATETIME
格式 根据我的需要。这就是为什么我将提取的数据存储到变量中 在打印之前。
这是我的代码:
-
//WHEN THE TEXT FROM TEXTBOX CHANGES:
protected void TextDate_TextChanged(object sender, EventArgs e)
{
//THE GRIDVIEW IS CREATED:
GridView1.DataSourceID = DatosLunes.ID;
GridView1.DataBind();
//A) I CREATE VARIABLES TO CHARGE THE DATA THAT CAMES FROM THE DATABASE WHEN PROCEED WITH THE QUERY
string VarsDateGV;
string VarsStartGV;
string VarsScchkGV;
string VarsEndGV;
string VarsDurationGV;
string VarsBeforeGV;
string VarsAfterGV;
//B) FOREACH ROW, THE PROCESS START TO:
foreach (GridViewRow row in GridView1.Rows)
{
//B.1) IDENTIFY EACH CONTROL INTO ROW COLUMNS:
TextBox DateGV = row.FindControl("DateGV") as TextBox;
TextBox StartGV = row.FindControl("StartGV") as TextBox;
TextBox ScchkGV = row.FindControl("ScchkGV") as TextBox;
TextBox EndGV = row.FindControl("EndGV") as TextBox;
TextBox DurationGV = row.FindControl("DurationGV") as TextBox;
HiddenField DedicatedGV = row.FindControl("DedicatedGV") as HiddenField;
HiddenField NotDedicatedGV = row.FindControl("NotDedicatedGV") as HiddenField;
DropDownList DropDownGV = row.FindControl("DropDownGV") as DropDownList;
TextBox BeforeGV = row.FindControl("BeforeGV") as TextBox;
TextBox AfterGV = row.FindControl("AfterGV") as TextBox;
DateTime FechaCT1 = DateTime.Parse(TextDate.Text, CultureInfo.InvariantCulture);
//B.2) IF THE [4] COLUMN STRING IS EQUAL TO "BATCH", THE ROW IS PAINTED
if (row.RowType == DataControlRowType.DataRow)
{
string NombreBatch = row.Cells[4].Text;
if (NombreBatch == "BATCH")
{
row.BackColor = System.Drawing.Color.NavajoWhite;
}
}
//B.3) THE QUERY STARTS
if (row.RowType == DataControlRowType.DataRow)
{
// B.3.1) EXTRACTS THE ROW ID FROM [0] COLUMN
string IDBatch = row.Cells[0].Text;
//B.3.2) USE A DATATABLE TO CHARGE DATA FROM THE QUERY "TRAEFILAHO"
CADCATOPS.DSCATOPS.BatchDatos1DataTable Fila = CADCATOPS.CADBatchHandoff.TraeFilaHO(Convert.ToInt32(IDBatch), Convert.ToString(FechaCT1));
//B.3.3) FOREACH ROW IN THE DATATABLE, THE DB INFORMATION IS SAVED INTO THE VARIABLES CREATED BEFORE (IN THE "A" ITEM).
foreach (DataRow row1 in Fila.Rows)
{
VarsDateGV = row1["FechaBatch"].ToString();
VarsStartGV = row1["Inicio"].ToString();
VarsScchkGV = row1["FinDedicado"].ToString();
VarsEndGV = row1["FinNoDedicado"].ToString();
VarsDurationGV = row1["DuracionBatch"].ToString();
DropDownGV.Text = row1["Estado"].ToString();
VarsBeforeGV = row1["DuracionBefore"].ToString();
VarsAfterGV = row1["DuracionAfter"].ToString();
/********* FROM NOW ON:
B.3.3.1) I VALIDATE IF THE DATETIME DATA EXTRACTED FROM THE DB EXISTS FOR A FEW ITEMS. IF EXISTS, THE FORMAT IS CHANGED FOR MY NEEDS, AND PRINTED.
MAYBE YOU ARE ASKING WHY I VALIDATE IT FOR SEPARATED AND NOT ALL TOGETHER, THIS IS BECAUSE I NEED TO CHECK IT SEPARATELLY.
IF "THIS" DATA DOESN'T EXISTS, DON'T BRING IT TO THE GRIDVIEW, BUT IF "THIS OTHER" DATA EXISTS, I NEED TO SHOW IT.
*********/
if (VarsDateGV != "")
{
DateTime VardDateGV = DateTime.Parse(VarsDateGV, CultureInfo.InvariantCulture);
DateTime VardStartGV = DateTime.Parse(VarsStartGV);
DateGV.Text = VardDateGV.ToString("MM/dd/yyyy");
StartGV.Text = VardStartGV.ToString("HH:mm");
}
if (VarsEndGV != "")
{
DateTime VardEndGV = DateTime.Parse(VarsEndGV);
DateTime VardDurationGV = DateTime.Parse(VarsDurationGV);
EndGV.Text = VardEndGV.ToString("HH:mm");
DurationGV.Text = VardDurationGV.ToString("HH:mm");
}
if (VarsScchkGV != "")
{
DateTime VardScchkGV = DateTime.Parse(VarsScchkGV);
ScchkGV.Text = VardScchkGV.ToString("HH:mm");
}
if (VarsBeforeGV != "")
{
DateTime VardBeforeGV = DateTime.Parse(VarsBeforeGV);
BeforeGV.Text = VardBeforeGV.ToString("HH:mm");
}
if (VarsAfterGV != "")
{
DateTime VardAfterGV = DateTime.Parse(VarsAfterGV);
AfterGV.Text = VardAfterGV.ToString("HH:mm");
}
}
}
} //FOREACH LOOP IS COMPLETED.
}
您对优化此事件有什么建议吗?
更新:ConnorsFan 帮助我检测问题(谢谢)。
问题出在查询上,因为它运行了 50 次(或 GridView
长度)。我试着避开它,响应时间不到 4 秒。问题是我需要它来处理查询。有没有办法为它优化代码?
最佳答案
那么总的迭代次数在100次左右。那应该不会花很长时间。
您能否在事件处理程序的开头和结尾使用 Stopwatch 类,并获得函数执行的总毫秒数 - 目前似乎没有任何理由认为代码会很慢。我们需要将代码的执行速度与刷新 UI 所花费的时间分开。
或者遵循此处的建议 How to suspend a DataGridView while updating its columns在执行更改期间暂停 GridView 绘制和重新格式化,然后在完成后恢复布局。
关于c# - 如何从 asp.net webform 中的 gridview 优化 "foreach"事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37702685/