2014-10-27 2 views
0

У меня есть класс, который обрабатывает datareading как таковой (Обратите внимание, что ischanged это событие, которое я поднимаю, чтобы указать наличие новой строки)DataReader Кормление управления DataGridView - построчно

public DataRow FetchNext() 
{ 
    DataRow drow = dt.NewRow(); 
    if (dr.Read() && dr.HasRows) //this will loop through rows unless cancel is clicked 
    { 
     try 
     { 
      for (int i = 0; i < listCols.Count; i++) 
      { 
       drow[(DataColumn)listCols[i]] = dr[i]; 
      } 
      dt.ImportRow(drow); 
      totalRowCount++; 
      this.isChanged(); 
      return drow; 
     } 
     catch (Exception ex) 
     { 
      throw; 
     } 
    } 
    else 
    { 
     return drow; 
    } 
} 

Другой класс который использует этот класс реализует чтение строки и вставляя их в DataGridView следующим образом (бс моего BindingSource, который связан с DataTable DT)

private void buttonGo_Click(object sender, EventArgs e) 
{ 
    myrow = p.FetchNext(); 
    this.dt = p.dt.Copy(); 
    bs.DataSource = dt; 
    dataGridViewMyData.DataSource = bs; 
    bs.ResetBindings(false);  
} 
private void handleChanged() 
{ 
    bs.ResetBindings(false); 
    dt.Rows.Add(p.FetchNext()); 
} 

Когда я огнем все вверх я получаю:

System.StackOverflowException was unhandled 
_HResult=-2147023895 

Любая помощь будет оценена по достоинству.

+1

Какая строка кода создает исключение? –

+0

цикл for в fetchnext() – Cogent

+1

будет этот 'dt.Rows.Add (p.FetchNext());' поднять событие 'handleChanged'? Если это так, то это бесконечный цикл. – TaW

ответ

0

Ok так вот ответ:

public DataRow FetchNext() 
{ 
    DataRow drow = dt.NewRow(); 
    if (dr.Read() && dr.HasRows) //this will loop through rows unless cancel is clicked 
    { 
     try 
     { 
      for (int i = 0; i < listCols.Count; i++) 
      { 
       drow[(DataColumn)listCols[i]] = dr[i]; 
      } 
      dt.ImportRow(drow); 
      totalRowCount++; 
      this.isChanged(); 
      return drow; 
     } 
     catch (Exception ex) 
     { 
      throw; 
     } 
    } 
    else 
    { 

     return drow; 
    } 
} 

В классе вызывающего я реализовал фоновый работник, который на DoWork: извлекает Далее. В то время как workcompleted также выбирает следующий, чтение значения isEnded каждый раз.

private void buttonGo_Click(object sender, EventArgs e) 
     { 
      myrow = p.FetchNext(); 
      this.dt = p.dt.Copy(); 
      bs.DataSource = dt; 
      dataGridViewMyData.DataSource = bs; 
      bs.ResetBindings(false); 
      if (!p.isEnded && !backgroundWorker1.IsBusy) 
      { 
       bs.SuspendBinding(); 
       backgroundWorker1.RunWorkerAsync(); 
      } 
     } 


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     bs.SuspendBinding(); 
     if (!p.isEnded) 
     { 
      dt.ImportRow(p.FetchNext()); 
     } 

    } 
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    bs.ResumeBinding(); 
    if (!p.isEnded) 
    { 

     backgroundWorker1.RunWorkerAsync(); 
    } 
    else 
    { 

     MessageBox.Show("Done"); 
    } 
    RefreshData(); 

} 

Это устранило проблему, и сетка действительно заполняется по строкам. Однако для запросов с сотнями тысяч строк это будет очень трудоемким.

Смежные вопросы