【问题标题】:how to find the coding execution time in c#?如何在c#中找到编码执行时间?
【发布时间】:2012-02-07 22:02:46
【问题描述】:

我正在使用 C#、winform 和 Mysql。 (Visual Studio 2010)。

在我的项目中,所有 menustrip 项都是不可见的。在登录时,它可以看到哪个 menustrip 项用户权限。为此,我看不见所有菜单条,。我为可见的菜单栏项目编码。

但它需要太多时间。超过 5 分钟。所以我有几个问题。

  1. 我如何找到这个编码执行时间? (下面是我的代码)....
  2. 有什么特殊的工具吗?
  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())
            {
                foreach (ToolStripMenuItem item in items)
                {
                    if (item.Name == Reader[0].ToString())
                    {
                        item.Visible = true;
                    }
                    else
                    {
                        menuActive(item.DropDown.Items);
                    }
                }
            }
            connection.Close();
        }

【问题讨论】:

  • 一种方法是使用称为分析器的工具。 .NET 有很多可用的。
  • 这段代码还能工作吗?您在 SqlDataReader 仍处于打开状态时递归调用该函数...
  • @zach,他创建了多个阅读器和连接,如果 sql server 支持多个连接,它会工作得很好。
  • @ZachGreen 如果启用MARS 可能会起作用

标签: c# performance visual-studio-2010


【解决方案1】:

您可以进行分析,但我可以直接看到一些明显的改进:

从数据库查询中分离出你的递归函数。这样您就可以查询一次数据库。请注意,它的作用并不完全相同,但我不确定该表是什么样的,因此您必须对其进行测试。

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); 
                } 
            }
    } 

【讨论】:

    【解决方案2】:

    是的,为每个菜单项创建一个 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();
            }
    

    【讨论】:

      【解决方案3】:

      问题 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 个项目,这需要 10000 次迭代,每次迭代都包括访问数据库以提供新数据。

      【讨论】:

        【解决方案4】:

        使用 StopWatch 类来计时执行,http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx。记录每个步骤后的时间,以确定需要这么长时间。

        【讨论】:

          【解决方案5】:

          您可以使用StopWatch class 来测试性能

          StopWatch sWatch = new StopWatch();
          sWatch.Start();
          // Code comes here
          ...
          sWatch.Stop();
          // sWatch.Elapsed // Contains the time interval
          

          您的递归似乎很糟糕 - 您一遍又一遍地在同一个集合上运行该函数。

          【讨论】:

            【解决方案6】:

            根据您的 VS 版本,您也许可以使用内置的 profiling tools 来查找时间花费的位置。

            【讨论】:

              【解决方案7】:

              对于问题 1 和 2,您可以使用 秒表

              Stopwatch watch = new Stopwatch();
              
              watch.Start();
              //YOUR CODE HERE
              watch.Stop();
              
              Console.WriteLine("Elapsed: {0}",watch.Elapsed);
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-10-28
                • 1970-01-01
                • 1970-01-01
                • 2015-03-14
                • 1970-01-01
                • 2013-06-06
                • 2010-12-24
                • 1970-01-01
                相关资源
                最近更新 更多