winforms C # .NET - วิธีการปรับปรุงประสิทธิภาพของรหัสของฉันในขณะที่ใช้ลูป (สำหรับ foreach ฯลฯ ... ) [ปิด]
ฉันกำลังพัฒนาแอพสำหรับวิทยาลัยส่วนหนึ่งของแอพคือการกำหนดตารางเรียนรายสัปดาห์
พารามิเตอร์ของฉันคือหมายเลข Classroom วันในสัปดาห์และช่วงเวลา
ดังนั้นฉันจึงมีห้องเรียนที่หลากหลายแต่ละห้องเรียนมีจำนวน
ใน Run-Time แอปจะสร้างปุ่มบางปุ่มตามจำนวนห้องเรียนที่ฉันมีในฐานข้อมูลของฉันและกำหนดหมายเลขห้องเรียนในแต่ละปุ่ม
สิ่งที่ฉันต้องการทำคือติดป้ายกำกับปุ่ม Classroom แต่ละปุ่มด้วย BackColor "สีแดง" หากห้องเรียนนั้นเต็มในวันของสัปดาห์และช่วงเวลาที่กำหนด
ฉันทำในสิ่งที่ฉันต้องการได้สำเร็จและโค้ดของฉันทำงานได้โดยไม่มีข้อผิดพลาด แต่ปัญหาเดียวของฉันตอนนี้คือประสิทธิภาพ
นี่คือรหัสของฉัน:
private OleDbConnection Connection = new OleDbConnection();
private void SomeMethod(string Day, string Time)
{
int MaxIndex = 0;
string str1 = "select Max([Row Index]) from Table";
OleDbCommand Command1 = new OleDbCommand(str1, Connection);
Connection.Open();
if (Command1.ExecuteScalar() == DBNull.Value)
MaxIndex = 1;
else
MaxIndex = Convert.ToInt32(Command1.ExecuteScalar());
Connection.Close();
for (int i = 0; i < MaxIndex; i++)
{
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime and [Row Index] = @ParamIndex";
OleDbCommand Command = new OleDbCommand(str, Connection);
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Command.Parameters.Add("@ParamIndex", i + 1);
Connection.Open();
OleDbDataReader reader = Command.ExecuteReader();
if (reader.Read())
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == reader["classroom Number"].ToString())
{
btn.BackColor = Color.Red;
}
}
Connection.Close();
}
}
}
ดังนั้นรหัสนี้จะใช้เวลาประมาณ 13 วินาทีถ้าฉันมี 200 แถวซึ่งฉันคาดว่าจะมี
คำถามคือ ... มีอะไรที่ฉันสามารถทำได้กับรหัสของฉันเพื่อให้ 13 วินาทีเหล่านี้ลดลงเหลืออย่างน้อย 2-4 วินาที?
สำหรับข้อมูล: ฉันได้ค้นหาข้อมูลมากมายบนอินเทอร์เน็ต แต่ไม่พบวิธีแก้ปัญหาของฉันที่นี่
คำตอบ
ดูเหมือนคุณจะไม่ต้องการวงจรเลย และMaxIndex
อย่างใดอย่างหนึ่ง เพียงดาวน์โหลดบันทึกสำหรับเวลาและทำเครื่องหมายปุ่ม
private void SomeMethod(string Day, string Time)
{
HashSet<string> classNumbers = new HashSet<string>();
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime";
using (OleDbCommand Command = new OleDbCommand(str, Connection))
{
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Connection.Open();
using (OleDbDataReader reader = Command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
classNumbers.Add(reader["classroom Number"].ToString());
}
}
}
foreach (Button btn in ButtonsPanel.Controls)
{
if (classNumbers.Contains(btn.Text))
{
btn.BackColor = Color.Red;
}
}
}
มีสองสิ่งที่คุณสามารถเปลี่ยนแปลงเพื่อปรับปรุง:
- เปิดและปิดการเชื่อมต่อเพียงครั้งเดียวซึ่งสามารถลดเวลาในการทำงานของโค้ดได้
- ดึงข้อมูลทั้งหมดที่คุณต้องการประมวลผลในแบบสอบถามเดียว
ตรวจสอบรหัสด้านล่าง:
private OleDbConnection Connection = new OleDbConnection();
private void SomeMethod(string Day, string Time)
{
int MaxIndex = 0;
string str1 = "select Max([Row Index]) from Table";
OleDbCommand Command1 = new OleDbCommand(str1, Connection);
Connection.Open();
if (Command1.ExecuteScalar() == DBNull.Value)
MaxIndex = 1;
else
MaxIndex = Convert.ToInt32(Command1.ExecuteScalar());
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime and [Row Index] between 1 and @ParamIndex";
OleDbCommand Command = new OleDbCommand(str, Connection);
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Command.Parameters.Add("@ParamIndex", MaxIndex);
OleDbDataReader reader = Command.ExecuteReader();
while (reader.Read())
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == reader["classroom Number"].ToString())
{
btn.BackColor = Color.Red;
}
}
}
Connection.Close();
}
ตามความคิดเห็นของฉันคุณจะต้องดำเนินการค้นหาเพียงครั้งเดียวและวนซ้ำชุดผลลัพธ์ สิ่งนี้จะมีประสิทธิภาพที่เพิ่มขึ้นเนื่องจากตอนนี้คุณเข้าถึง IO ได้เพียงครั้งเดียวเนื่องจากโดยทั่วไปแล้ว IO จะช้ามาก
นี่คือตัวอย่าง (ยังไม่ได้ทดสอบ):
private void SomeMethod(string day, string time)
{
// Using statement helps to dispose any resources once done with the connection
// connectionString can be any string that opens your database
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
// The query has removed the notion of index, it will just get all the data for that day and time
string query = "SELECT [classroom Number] FROM Table WHERE [Day] = @ParamDay AND [Time] = @ParamTime";
// Since OleDbCommand inherits from IDisposable, use a using statement
using (OleDbCommand command = new OleDbCommand(query, connection))
{
// Notice how we don't use index anymore
command.Parameters.Add("@ParamDay", day);
command.Parameters.Add("@ParamTime", time);
// Open connection here, don't need to close connection
connection.Open();
// Since OleDbDataReader inherits from IDisposable, use a using statement
using (OleDbDataReader reader = command.ExecuteReader())
{
// We're now looping through all the rows in the result set
while (reader.Read())
{
UpdateButtonColor(reader["classroom Number"].ToString());
}
}
}
}
}
private void UpdateButtonColor(string classroomNumber)
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == classroomNumber)
{
btn.BackColor = Color.Red;
}
}
}
C # เวอร์ชันใหม่กว่าอนุญาตให้using
คำสั่งไม่ต้องใช้วงเล็บปีกกา (ซึ่งช่วยลดการซ้อน) ซึ่งจะมีลักษณะดังนี้:
private void SomeMethod(string day, string time)
{
string query = "SELECT [classroom Number] FROM Table WHERE [Day] = @ParamDay AND [Time] = @ParamTime";
using OleDbConnection connection = new OleDbConnection(connectionString);
using OleDbCommand command = new OleDbCommand(query, connection);
command.Parameters.Add("@ParamDay", day);
command.Parameters.Add("@ParamTime", time);
connection.Open();
using OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
UpdateButtonColor(reader["classroom Number"].ToString());
}
}
เอกสารสำหรับสิ่งนี้สามารถพบได้ที่นี่