我在C#,winform和Mysql中工作。 (Visual Studio 2010)。
在我的项目中,所有menustrip项目都是不可见的。在登录时,其可见的menustrip项目用户权限。为此,我看不见所有菜单条。我编码可以看到menustrip项目。
但是花了太多时间。超过5分钟。所以我有几个问题。
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(); }
答案 0 :(得分:3)
你可以描述,但我可以直接看到一些明确的改进:
将远离数据库查询的重复函数分开。这样您就可以查询一次数据库。请注意,它并没有完全相同,但我不确定该表是什么样的,所以你必须测试它。
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);
}
}
}
答案 1 :(得分:1)
是的,为每个菜单项创建一个dbase连接需要一段时间。你需要避免在foreach循环中调用MenuActive()。用一个小帮手方法让它变得更聪明:
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;
}
并称之为:
...
while (Reader.Read())
{
EnableMenuItem(items, Reader[0].ToString();
}
答案 2 :(得分:1)
问题1和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;
}
问题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);
}
}
}
鉴于您在数据库中有1000条记录和10个项目,这需要10 000次迭代,每次迭代包括访问数据库以提供新数据。
答案 3 :(得分:0)
使用StopWatch类为执行计时http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx。记录每个步骤后的时间,以确定需要花费的时间。
答案 4 :(得分:0)
您可以使用StopWatch class来测试效果
StopWatch sWatch = new StopWatch();
sWatch.Start();
// Code comes here
...
sWatch.Stop();
// sWatch.Elapsed // Contains the time interval
看起来你的递归很糟糕 - 你一遍又一遍地对同一个集合运行这个函数。
答案 5 :(得分:0)
根据您的VS版本,您可以使用内置profiling tools来查找花费的时间。
答案 6 :(得分:0)
对于问题1和2,您可以使用秒表:
Stopwatch watch = new Stopwatch();
watch.Start();
//YOUR CODE HERE
watch.Stop();
Console.WriteLine("Elapsed: {0}",watch.Elapsed);