Click here to Skip to main content
15,886,026 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);
      }
 
Share this answer
 

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