Reputation: 2626
I am working in C#, winform and Mysql. (Visual Studio 2010).
In my project all menustrip items are invisable. At the login time its visible which menustrip item user rights. For that i invisible all menu strip,. And I code for visible the menustrip items.
But its take too much time. more then 5 minutes. So I have Few Questions.
private void menuActive(ToolStripItemCollection items) { hp.getConnStr(); MySqlConnection connection = new MySqlConnection(hp.myConnStr); MySqlCommand command = connection.CreateCommand(); MySqlDataReader Reader; command.CommandText = "select menu_key from mcs_menu_rights where userid ='"+userId+"'"; connection.Open(); Reader = command.ExecuteReader(); while (Reader.Read()) { foreach (ToolStripMenuItem item in items) { if (item.Name == Reader[0].ToString()) { item.Visible = true; } else { menuActive(item.DropDown.Items); } } } connection.Close(); }
Upvotes: 0
Views: 1266
Reputation: 35895
Question 1 and 2
var time = TimeAction(() =>
{
//CODE here
});
private static TimeSpan TimeAction(Action action)
{
var sw = new Stopwatch();
sw.Start();
action.Invoke();
sw.Stop();
return sw.Elapsed;
}
Question 3
//One loop through all records in database
while (Reader.Read())
{
//Another loop through all the control
foreach (ToolStripMenuItem item in items)
{
if (item.Name == Reader[0].ToString())
{
item.Visible = true;
}
else
{
menuActive(item.DropDown.Items);
}
}
}
Given you have 1000 records in a database and 10 items, this take 10 000 iterations, each including trip to database to serve new data.
Upvotes: 1
Reputation: 54781
You could profile, but there are some definite improvements I can see straight off:
Seperate out your recusive function away from the database query. This way you query the database once. Note that it's not doing exactly the same, but I'm not sure what that table looks like so you'll have to test it.
private void menuActive(ToolStripItemCollection items)
{
hp.getConnStr();
MySqlConnection connection = new MySqlConnection(hp.myConnStr);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader Reader;
command.CommandText = "select menu_key from mcs_menu_rights where userid ='"+userId+"'";
connection.Open();
Reader = command.ExecuteReader();
while (Reader.Read())
{
var nameFromDB = Reader[0].ToString();
setMenuActiveByName(items, nameFromDB);
}
connection.Close();
}
//This is the recursive bit, but doesn't re-enquire the database
private void setMenuActiveByName(ToolStripItemCollection items, string name)
{
foreach (ToolStripMenuItem item in items)
{
if (item.Name == name)
{
item.Visible = true;
}
else
{
setMenuActiveByName(item.DropDown.Items, name);
}
}
}
Upvotes: 3
Reputation: 941218
Yes, creating a dbase connection for every single menu item is going to take a while. You'll need to avoid calling MenuActive() inside the foreach loop. Make it smarter with a little helper method:
private static bool EnableMenuItem(ToolStripItemCollection items, string name) {
foreach (ToolStripMenuItem item in items) {
if (item.Name == name) {
item.Visible = true;
return true;
}
else if (item.DropDown.Items.Count > 0 {
if (EnableMenuItem(item.DropDown.Items, name)) return true;
}
}
return false;
}
And call it like this:
...
while (Reader.Read())
{
EnableMenuItem(items, Reader[0].ToString();
}
Upvotes: 1
Reputation: 992
For questions 1 and 2, you can use stopwatch:
Stopwatch watch = new Stopwatch();
watch.Start();
//YOUR CODE HERE
watch.Stop();
Console.WriteLine("Elapsed: {0}",watch.Elapsed);
Upvotes: 0
Reputation: 38179
Depending on your version of VS, you might be able to use the builtin profiling tools to find where the time is spent.
Upvotes: 0
Reputation: 25619
You can use the StopWatch class for testing performance
StopWatch sWatch = new StopWatch();
sWatch.Start();
// Code comes here
...
sWatch.Stop();
// sWatch.Elapsed // Contains the time interval
It seems like you have a bad recursion there - you run the function on the same collection over and over.
Upvotes: 0
Reputation: 3460
Use the StopWatch class to time the execution, http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx. Log the time after each step to determine what is taking so long.
Upvotes: 0