从数据库中获取动态按钮需要太长时间

时间:2015-02-16 21:54:48

标签: c# mysql database multithreading

我正在开发一个POS窗口应用程序,我希望它很快,但是当我从MySql中获取数据时,需要5秒才能获取一张餐馆的100张桌子。 这里的任何人都可以告诉我有没有办法在应用程序启动时从数据库加载数据,所以我可以稍后调用它们,而不是每次打开表格时都等待它?

这是一个代码示例:

FlowLayoutPanel flp = new FlowLayoutPanel();
            conn.Open();
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            MySqlDataAdapter adapter = new MySqlDataAdapter("SELECT * FROM tables ORDER BY number_of_table", conn);
            adapter.Fill(dt);
            ds.Tables.Add(dt);
            foreach (DataRow dr in dt.Rows)
            {
                Button b = new Button();
                b.BackColor = Color.FromArgb(241, 234, 182);
                b.FlatStyle = FlatStyle.Flat;
                b.Size = new Size(100, 100);
                b.Text = dr[1].ToString();
                b.Tag = dr[2].ToString();
                b.Click += new EventHandler(OpenTavolina);
                flowLayoutPanel1.Controls.Add(b);
            }
            conn.Close();

3 个答案:

答案 0 :(得分:3)

你确定这是sql查询花了5秒钟吗?如果是这样,您有一个严重的数据库问题,您需要清理联接和添加索引,或者可能有一个糟糕的Internet连接。我怀疑从开始到画完的整个操作是5秒。如果您可以将数据请求和按钮绘图拆分为两个不同的功能,则可以对它们进行计时。

最有可能的是,100回流,重拍你正在表演。

如果瓶颈是用户界面,请在添加按钮之前尝试将流更新面板设置为visible = false,然后将其设置回visible = true。

- 发现问题后的编辑1是使用回流:

您可以为缓存创建静态类。

例如

......

public static class DataManager
{   
   public static List<Button> FormButtons {get; set;}

   static DataManager()
   {
      FormButtons = new List<Button>();
   }

   public static void LoadButtonsOnce()
   {
          //build buttons from database and perform a...

          FormButtons.Add(newButton) 
   }

}

现在您可以在任何地方访问DataManager.FormButtons ...

请记住,这仍然无法解决重绘/重排的问题。你仍然需要执行.visible hack来解决这个问题。

答案 1 :(得分:2)

加载100个只有三列的记录时,数据库不太可能出现性能问题。

相反,问题将是将100个子控件添加到布局面板的100个单独调用。每次添加新子项时,它都将执行布局处理周期。

要解决此问题,您可以指示控件暂停处理布局,直到添加完子控件。所以在 foreach 循环之前......

floatLayoutPanel1.SuspendLayout();

...然后在 foreach 循环后再次允许布局处理...

floatLayoutPanel1.ResumeLayout();

然后你唯一的布局处理就打了一次。如果查看任何具有布局控件的Form的生成代码,您将看到它在代码的开头和结尾自动生成这些调用。

答案 2 :(得分:1)

您的第一个问题是您的查询本身。您正在执行select * from ...从不执行select *,而是通过仅返回所需的特定列来优化查询。例如,如果dr [1]是名为&#39; name_of_table&#39;的字段。 and dr [2]是一个名为&#39; number_of_table&#39;的字段,那么您的查询应该只有select name_of_table, number_of_table ...

作为旁注,请勿访问c#代码中的字段,例如dr[1]。这使得其他开发人员很难进入并处理您的代码。此外,如果其他开发人员更改了查询,则列所在的索引将更改。始终使用列名称,如dr["name_of_table"]。这样,无论“选择”中的字段存在于何处,它都不会失败。