Click here to Skip to main content
14,879,139 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a C# WinForm dataGridView that's unbound and implements virtual mode. I'm initiating my queries in real-time and having performance issues when the user scrolls to render data to new rows. My winForm freezes and my memory keeps growing with each scroll/query and cpu usage is near 50%. Here's a code example. What am I doing wrong here?

class MyForm : Form
{
   DataGridView dgv = new DataGridView();
   DataRetriever dataretriever = new DataRetriever();

   public MyForm()
   {
      dgv.AllowUserToAddRows = false;
      dgv.AllowUserToDeleteRows = false;
      dgv.ReadOnly = false;
      dgv.VirtualMode = true;
      dvg.Columns.Add("colID","ID");
      dvg.Columns.Add("colVal","Val");
      dgv.AddRows.Add();
      dgv.Rows.Copies(0,300000);
      dgv.CellValueNeeded += dgv_CellValueNeeded;
   }

   void Button1_Click(object sender, EventArgs e)
   {
      dataretriever.LoadData();
      grid.Refresh();
   }

   void dgv_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
   {
      MyData mydata = dataretriever.GetRow(e.RowIndex);
  
      while(mydata == null)
      {
         mydata.LoadData();
         mydata = dataretriever.GetData(e.RowIndex);
      }

      switch(dgv.Columns[e.ColumnIndex].Name)
      {
         case "colID":
              e.Value = mydata.id;
         case "colVal":
              e.Value = mydata.val;
      }
}

class DataRetriever
{
  string connStr = null;
  SQLConn conn = null; 
  SQLCommand cmd = null;
  SQLDataReader rdr = null;

  int lastrow = 0;

  Dictionary<int, MyData> cache = new Dictionary<int, MyData>();
  
  public MyData GetData(int row)
  {
    if (row < 0)
        return;
    if (cache.ContainsKey(row))
    {
       return cache[row];
    }
    else
    {
      return null;
    }
  }

  public int LoadData()
  {
    fetch();
    return lastrow;
  }

  private void fetch()
  {
    conn = new SQLConn(connStr);
    cmd = new SQLCommand();
    cmd.Connection = conn;

    try
    {
       conn.Open();
       
       // SQL 
       string sql = "SELECT tbl1.ID, tbl2.Name, tbl2.Date, etc..." +
                    "FROM table1 tbl1 JOIN table2 tbl2, etc..." +
                    "ON tbl1._id = tbl2.id, WHERE..."

       // user filters based on GUI settings
       if(textbox1.Text > 0)
       {
          sql += "AND tbl1.whatever = " + textbox1.Text;
       }
       // more filtering based on user input into GUI
       
       sql += "LIMIT 100 OFFSET " + lastrow;
  
       cmd.CommandText = sql;
    
       rdr = cmd.ExecuteReader();
      
       while(rdr.Read())
       {
          int id = rdr["ID"];
          int val = rdr["Val"];

          cache.Add(lastrow, new MyData(id,val));
          ++lastrow;
       }
       rdr.Close();
    }
    catch(Exception ex)
    {
    }
    finally
    {
       conn.Close();
       cmd.Close();
    }
  }
}

class MyData
{
   public int ID;
   public int Val;
   
   public MyData(int id, int val)
   {
      ID = id;
      Val = val;
   }
}
Posted
Updated 19-Apr-13 13:05pm
v4

1 solution

C#
while(mydata == null)
      {
         mydata.LoadData();
         mydata = dataretriever.GetData(e.RowIndex);
      }
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900