通过DataTable迭代非常慢

时间:2015-07-29 14:55:01

标签: c# asp.net datagridview datatable

我对webforms / windowsforms的经验很少。去年,我作为开发人员开始从事第一份工作,开始使用MVC Web开发,这就是我自那以后所做的一切。

我父亲最近要我创建一个简单的应用程序,我决定尝试使用Windows Forms。该应用程序的作用是使用OLEDB将Excel工作表文件读取到DataTable并在DataGridView上显示:

enter image description here

enter image description here

完成此操作后,每列都与一组预定义标签匹配,然后按以下格式写入txt文件:

@tag    (column value)

我作为一个例子使用的excel文件有大约18k行。使用OLEDB读取文件并将其绑定到DataGridView几乎是即时的(1/2到2秒)。但是,当我使用适当的标记匹配列并生成所需的输出时,它需要非常长的时间(5分钟)。考虑到DataTable在此阶段处于记忆中,这感觉是错误的。我不确定我是否会以DataTable进行迭代并且效率极低。

下面是遍历DataTable以创建输出的代码:

private void GenerateOutputButton_Click(object sender, EventArgs e)
{
    OutputDisplayRichText.Clear();
    output = string.Empty;

    string selectedT = TComboBox.SelectedItem.ToString(),
           selectCDocdate = CDocdateComboBox.SelectedItem.ToString(),
           selectedCSubject = CSubjectCombobox.SelectedItem.ToString(),
           selectedTiff = TiffComboBox.SelectedItem.ToString();

    foreach (DataRow row in excelSheet.Rows)
    {
        if (TToken.Checked)
        {
            /*..removed code..*/
            output += "@T\t\t" + tempOutput + Environment.NewLine;
        }
        if (CDocdateToken.Checked)
        {
            string rowValue = row[selectCDocdate].ToString();
            string tempOutput = "@C Docdate\t\t" + rowValue + Environment.NewLine;
            output += tempOutput;
        }
        if (CSubjectToken.Checked)
        {
            string rowValue = row[selectedCSubject].ToString();
            string tempOutput = "@C Subject\t\t" + rowValue + Environment.NewLine;
            output += tempOutput;
        }
        if (DToken.Checked)
        {
            string rowValue = DTextBox.Text;
            string tempOutput = "@D \t\t" + rowValue + Environment.NewLine;
            output += tempOutput;
        }
        if (TiffFiles.Checked)
        {
            /*..removed code..*/
            output = TTextBox.Text + "{" + pageFromStr2 + "-" + pageToStr2 + "}.tif";
        }

        output += Environment.NewLine;
    }

    OutputDisplayTextBox.Text = output;
}

2 个答案:

答案 0 :(得分:2)

字符串是不可变的,这意味着它们不能在内存中更改。您将大量信息附加到字符串变量中 - 这会在内存中创建许多重复的字符串,占用越来越多的内存并降低应用程序的速度。

使用StringBuilder类 - 这是可变的。例如:

Stringbuilder builder = new StringBuilder();
builder.AppendLine("text"); // adds a new line to the StringBuilder

当您需要输出文本时,请在StringBuilder实例上调用.ToString()

答案 1 :(得分:1)

.net中的

string是不可变的,因此,每次使用+运算符连接两个字符串/值时,您创建一个新字符串并保留.net中的其他字符串从内存中删除它。要避免此问题,您可以使用StringBuilder实例作为示例:

StringBuilder b = new StringBuilder();

foreach (DataRow row in excelSheet.Rows)
{
    if (TToken.Checked)
        b.AppendLine(string.Format("@T\t\t{0}", tempOutput));

    if (CDocdateToken.Checked)
        b.AppendLine(string.Format("@C Docdate\t\t{0}", row[selectCDocdate].ToString()));

    if (CSubjectToken.Checked)
        b.AppendLine(string.Format("@C Subject\t\t{0}", row[selectedCSubject].ToString())); 

    if (DToken.Checked)
        b.AppendLine(string.Format("@D \t\t{0}", DTextBox.Text));   

    if (TiffFiles.Checked)
        b.Append(TTextBox.Text + "{" + pageFromStr2 + "-" + pageToStr2 + "}.tif");

    b.AppendLine();
}

// generate everything in a single string.
output = b.ToString();

根据您的代码调整它,因为我们没有详细信息。