【问题标题】:DataReader Feeding a DatagridView Control - Row by RowDataReader 提供 DatagridView 控件 - 逐行
【发布时间】:2014-10-27 13:04:46
【问题描述】:

我有一个处理数据读取的类(请注意,ischanged 是我提出的一个事件,以指示新行的可用性)

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中(bs是我绑定到datatable dt的bindingsource)

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

任何帮助将不胜感激。

【问题讨论】:

  • 哪一行代码产生异常?
  • fetchnext() 中的 for 循环
  • 这个dt.Rows.Add(p.FetchNext()); 会引发handleChanged 事件吗?如果是这样,它是一个无限循环..
  • 这会引发stackoverflow异常吗?
  • 如果无限循环声明任何资源,它将引发 stackoverflowexception 或 outofmemory 异常。如果不是,它只会挂起.. addRow 肯定会要求资源。

标签: c# datagridview sqldatareader stack-overflow


【解决方案1】:

好的,答案如下:

    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 上:获取 Next。虽然 workcompleted 还会获取 next,但每次都读取 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();

}

这确实解决了问题,并且网格确实是逐行填充的。但是,对于具有数十万行的查询,这将非常耗时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    相关资源
    最近更新 更多