Manera más rápida de leer csv a grilla

He seguido en Windows Forms .NET 3.5

Funciona bien para CSV con registros de menos de 10,000, pero es más lento para registros de más de 30,000. El archivo csv de entrada puede hacer cualquier registro entre 1 – 1,00,000 registros

Código utilizado actualmente:

///  /// This will import file to the collection object ///  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; } } 

Ejemplo de archivo de entrada:
18906, Y
18908, Y
18909, Y
18910, Y
18912, N
18913, N

Necesita algún consejo para optimizar este código para lecturas rápidas y ver en cuadrícula.

 List 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; 

Inténtalo, sospechaba que tenías algún tipo de nombres de columna en el datagrid, por ahora acabo de hacer 1 y 2.

Para filtrar según su código original use:

 List rows = File.ReadAllines("Path").Select(x => x.Split(',')).Where(x => x[0] != "" && x[1] != "").ToList(); 

Para obtener sus columnas de la DataGridView

  dt.Columns.AddRange(dgv.Columns.Cast().Select(x => new DataColumn(x.Name)).ToArray()); 

No hay mucho que optimizar con respecto a la velocidad, pero seguir es mucho más fácil de leer. Si es demasiado lento, probablemente no sea el método que lee el archivo, sino su WinForm que necesita mostrar> 30k registros.

  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); } } } 

Puede intentar usar los métodos SuspendLayout () y ResumeLayout () .

De la documentación de MSDN “Los métodos SuspendLayout y ResumeLayout se usan en tándem para suprimir múltiples eventos de diseño mientras se ajustan múltiples atributos del control. Por ejemplo, normalmente se llama el método SuspendLayout, luego se establecen las propiedades Tamaño, Ubicación, Ancla o Dock del control, y luego llame al método ResumeLayout para permitir que los cambios surtan efecto “.

 accountsDataGridView.SuspendLayout(); accountsDataGridView.Rows.Clear(); // ..... // in the end after you finished populating your grid call accountsDataGridView.ResumeLayout(); 

En lugar de colocar los datos directamente en la cuadrícula, debería echar un vistazo a la VirtualMode de DataGridView .

En tu código estás haciendo dos cosas a la vez (lee el archivo, llena la cuadrícula), lo que lleva a tu gui congelado. En su lugar, debe colocar la cuadrícula en el modo virtual y leer el archivo dentro de un BackgroundWorker en una lista que contenga los datos de la cuadrícula. El trabajador de fondo puede, después de cada lectura de línea, actualizar el tamaño virtual de la cuadrícula, lo que permite ver los datos mientras se carga la cuadrícula. Mediante el uso de este enfoque obtendrá una cuadrícula de trabajo sin problemas.

A continuación encontrará un ejemplo que solo debe rellenarse en un formulario que utiliza un DataGridView con dos columnas de texto, un BackgroundWorker y un Button :

 public partial class FormDemo : Form { private List _Elements; public FormDemo() { InitializeComponent(); _Elements = new List(); 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; } } }