C# 将csv读取到网格的更快方法

C# 将csv读取到网格的更快方法,c#,.net,winforms,csv,datagridview,C#,.net,Winforms,Csv,Datagridview,我在WindowsForms.NET3.5中有以下内容 它适用于记录少于10000条的csv,但对于记录超过30000条的csv则较慢。 输入csv文件可以保存1-100000条记录之间的任何记录 当前使用的代码: /// <summary> /// This will import file to the collection object /// </summary> private bool ImportFile()

我在WindowsForms.NET3.5中有以下内容

它适用于记录少于10000条的csv,但对于记录超过30000条的csv则较慢。 输入csv文件可以保存1-100000条记录之间的任何记录

当前使用的代码:

/// <summary>
        /// This will import file to the collection object
        /// </summary>
        private bool ImportFile()
        {
            try
            {

                String fName;
                String textLine = string.Empty;
                String[] splitLine;

                // clear the grid view

                accountsDataGridView.Rows.Clear();

                fName = openFileDialog1.FileName;

                if (System.IO.File.Exists(fName))
                {
                    System.IO.StreamReader objReader = new System.IO.StreamReader(fName);

                    do
                    {
                        textLine = objReader.ReadLine();
                        if (textLine != "")
                        {
                            splitLine = textLine.Split(',');
                            if (splitLine[0] != "" || splitLine[1] != "")
                            {
                                accountsDataGridView.Rows.Add(splitLine);
                            }
                        }
                    } while (objReader.Peek() != -1);
                }
                return true;
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("The process cannot access the file"))
                {
                    MessageBox.Show("The file you are importing is open.", "Import Account", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    MessageBox.Show(ex.Message);
                }

                return false;
            }

        }
//
///这将文件导入到集合对象
/// 
私有布尔导入文件()
{
尝试
{
字符串fName;
String textLine=String.Empty;
字符串[]分隔线;
//清除栅格视图
accountsDataGridView.Rows.Clear();
fName=openFileDialog1.FileName;
if(System.IO.File.Exists(fName))
{
System.IO.StreamReader objReader=新的System.IO.StreamReader(fName);
做
{
textLine=objReader.ReadLine();
如果(文本行!=“”)
{
splitLine=textLine.Split(',');
如果(分割线[0]!=“”| |分割线[1]!=“”)
{
accountsDataGridView.Rows.Add(拆分行);
}
}
}while(objReader.Peek()!=-1);
}
返回true;
}
捕获(例外情况除外)
{
if(例如Message.Contains(“进程无法访问文件”))
{
Show(“您正在导入的文件已打开。”,“导入帐户”,MessageBoxButtons.OK,MessageBoxIcon.Warning);
}
其他的
{
MessageBox.Show(例如Message);
}
返回false;
}
}
示例输入文件:
18906年,Y
18908年,Y
18909年,Y
18910年,Y
18912年,N
18913年,N


需要一些关于优化此代码以在网格中快速读取和查看的建议。

不要将数据直接放入网格中,您应该查看

List<string[]> rows = File.ReadAllLines("Path").Select(x => x.Split(',')).ToList();
DataTable dt = new DataTable();
dt.Columns.Add("1");
dt.Columns.Add("2");
rows.ForEach(x => {
  dt.Rows.Add(x);
});
dgv.DataSource = dt;
在您的代码中,您一次要做两件事(读取文件,填充网格),这将导致您的gui冻结。相反,您应该将网格置于虚拟模式,并将
BackgroundWorker
中的文件读取到保存网格数据的列表中。后台工作程序可以在每行读取后更新网格的虚拟大小,这样就可以在网格加载时查看数据。通过使用这种方法,您将获得一个平滑的工作网格

下面您将看到一个示例,它只需要填写到一个表单中,该表单使用一个带有两个文本列的
DataGridView
,一个
BackgroundWorker
和一个
按钮

public partial class FormDemo : Form
{
    private List<Element> _Elements;

    public FormDemo()
    {
        InitializeComponent();
        _Elements = new List<Element>();

        dataGridView.AllowUserToAddRows = false;
        dataGridView.AllowUserToDeleteRows = false;
        dataGridView.ReadOnly = true;
        dataGridView.VirtualMode = true;
        dataGridView.CellValueNeeded += OnDataGridViewCellValueNeeded;

        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.DoWork += OnBackgroundWorkerDoWork;
        backgroundWorker.ProgressChanged += OnBackgroundWorkerProgressChanged;
        backgroundWorker.RunWorkerCompleted += OnBackgroundWorkerRunWorkerCompleted;
    }

    private void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
    {
        var filename = (string)e.Argument;

        using (var reader = new StreamReader(filename))
        {
            string line = null;

            while ((line = reader.ReadLine()) != null)
            {
                var parts = line.Split(',');

                if (parts.Length >= 2)
                {
                    var element = new Element() { Number = parts[0], Available = parts[1] };
                    _Elements.Add(element);
                }

                if (_Elements.Count % 100 == 0)
                {
                    backgroundWorker.ReportProgress(0);
                }
            }
        }
    }

    private void OnBackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        dataGridView.RowCount = _Elements.Count;
    }

    private void OnBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        dataGridView.RowCount = _Elements.Count;
        button.Enabled = true;
    }

    private void OnButtonLoadClick(object sender, System.EventArgs e)
    {
        if (!backgroundWorker.IsBusy
            && DialogResult.OK == openFileDialog.ShowDialog())
        {
            button.Enabled = false;
            backgroundWorker.RunWorkerAsync(openFileDialog.FileName);
        }
    }

    private void OnDataGridViewCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        var element = _Elements[e.RowIndex];

        switch (e.ColumnIndex)
        {
            case 0:
                e.Value = element.Number;
                break;

            case 1:
                e.Value = element.Available;
                break;
        }
    }

    private class Element
    {
        public string Available { get; set; }

        public string Number { get; set; }
    }
}
public分部类FormDemo:Form
{
私有列表元素;
public FormDemo()
{
初始化组件();
_元素=新列表();
dataGridView.AllowUserToAddress=false;
dataGridView.AllowUserToDeleteRows=false;
dataGridView.ReadOnly=true;
dataGridView.VirtualMode=true;
dataGridView.CellValueRequired+=OnDataGridViewCellValueRequired;
backgroundWorker.WorkerReportsProgress=true;
backgroundWorker.DoWork+=OnBackgroundWorkerDoWork;
backgroundWorker.ProgressChanged+=OnBackgroundWorkerProgressChanged;
backgroundWorker.RunWorkerCompleted+=OnBackgroundWorkerRunWorkerCompleted;
}
BackgroundWorkerDoWork上的私有void(对象发送方,DoWorkerVentargs e)
{
var filename=(字符串)e.参数;
使用(var reader=newstreamreader(文件名))
{
字符串行=null;
而((line=reader.ReadLine())!=null)
{
var parts=line.Split(',');
如果(零件长度>=2)
{
var element=new element(){Number=parts[0],Available=parts[1]};
_元素。添加(元素);
}
如果(_Elements.Count%100==0)
{
backgroundWorker.ReportProgress(0);
}
}
}
}
BackgroundWorkerProgressChanged上的私有void(对象发送方,ProgressChangedEventArgs e)
{
dataGridView.RowCount=\u Elements.Count;
}
BackgroundWorkRRunWorkerCompleted上的私有无效(对象发送方,RunWorkerCompletedEventArgs e)
{
dataGridView.RowCount=\u Elements.Count;
button.Enabled=true;
}
私有void OnButtonLoadClick(对象发送方,System.EventArgs e)
{
如果(!backgroundWorker.IsBusy
&&DialogResult.OK==openFileDialog.ShowDialog()
{
按钮。已启用=错误;
backgroundWorker.RunWorkerAsync(openFileDialog.FileName);
}
}
私有void OnDataGridViewCellValueRequired(对象发送方,DataGridViewCellValueEventArgs e)
{
var元素=_元素[e.RowIndex];
开关(如列索引)
{
案例0:
e、 值=元素编号;
打破
案例1:
e、 值=元素。可用;
打破
}
}
私有类元素
{
可用的公共字符串{get;set;}
公共字符串编号{get;set;}
}
}

不要将数据直接放入网格,而应该查看

在您的代码中,您一次要做两件事(读取文件,填充网格),这将导致您的gui冻结。相反,您应该将网格置于虚拟模式,并将
BackgroundWorker
中的文件读取到保存网格数据的列表中。后台工作程序可以在每行读取后更新网格的虚拟大小,这样就可以在网格加载时查看数据。通过使用这种方法,您可以
  dt.Columns.AddRange(dgv.Columns.Cast<DataGridViewColumn>().Select(x => new DataColumn(x.Name)).ToArray());
public partial class FormDemo : Form
{
    private List<Element> _Elements;

    public FormDemo()
    {
        InitializeComponent();
        _Elements = new List<Element>();

        dataGridView.AllowUserToAddRows = false;
        dataGridView.AllowUserToDeleteRows = false;
        dataGridView.ReadOnly = true;
        dataGridView.VirtualMode = true;
        dataGridView.CellValueNeeded += OnDataGridViewCellValueNeeded;

        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.DoWork += OnBackgroundWorkerDoWork;
        backgroundWorker.ProgressChanged += OnBackgroundWorkerProgressChanged;
        backgroundWorker.RunWorkerCompleted += OnBackgroundWorkerRunWorkerCompleted;
    }

    private void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
    {
        var filename = (string)e.Argument;

        using (var reader = new StreamReader(filename))
        {
            string line = null;

            while ((line = reader.ReadLine()) != null)
            {
                var parts = line.Split(',');

                if (parts.Length >= 2)
                {
                    var element = new Element() { Number = parts[0], Available = parts[1] };
                    _Elements.Add(element);
                }

                if (_Elements.Count % 100 == 0)
                {
                    backgroundWorker.ReportProgress(0);
                }
            }
        }
    }

    private void OnBackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        dataGridView.RowCount = _Elements.Count;
    }

    private void OnBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        dataGridView.RowCount = _Elements.Count;
        button.Enabled = true;
    }

    private void OnButtonLoadClick(object sender, System.EventArgs e)
    {
        if (!backgroundWorker.IsBusy
            && DialogResult.OK == openFileDialog.ShowDialog())
        {
            button.Enabled = false;
            backgroundWorker.RunWorkerAsync(openFileDialog.FileName);
        }
    }

    private void OnDataGridViewCellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        var element = _Elements[e.RowIndex];

        switch (e.ColumnIndex)
        {
            case 0:
                e.Value = element.Number;
                break;

            case 1:
                e.Value = element.Available;
                break;
        }
    }

    private class Element
    {
        public string Available { get; set; }

        public string Number { get; set; }
    }
}
    accountsDataGridView.Rows.Clear();
    using (FileStream file = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096))
    using (StreamReader reader = new StreamReader(file))
    {
        while (!reader.EndOfStream)
        {
            var fields = reader.ReadLine().Split(',');
            if (fields.Length == 2 && (fields[0] != "" || fields[1] != ""))
            {
                accountsDataGridView.Rows.Add(fields);
            }
        }
    }
accountsDataGridView.SuspendLayout();
accountsDataGridView.Rows.Clear();

// .....
// in the end after you finished populating your grid call

accountsDataGridView.ResumeLayout();