Have a CSV, 34570 rows with 169 columns...
this CSV read & added to a datatable and loaded to DataGridView through DataSource property
or
advantage = very quick load takes ~4 seconds (125mb in memory)
cons = very slow, on executing LINQ and when set visibility to rows
notes :
--
approach 1
add rows by hand :
tried any possible variant apart List<T>, all of them had the same result.
advantage = LINQ and visibility to rows extremely fast
cons = takes ~12 seconds. (700mb in memory, even call SetProcessWorkingSetSize)
possible solution to use VirtualMode
Fast custom formulae, filtering and sorting in DataGrids
MS - Best Practices for Scaling the Windows Forms DataGridView Control
MS - Virtual Mode in the Windows Forms DataGridView Control
this CSV read & added to a datatable and loaded to DataGridView through DataSource property
C#:
DataTable dt = General.ImportDelimitedFile(file4import, delimiter, col_headers);
dg.DataSource = dt;
or
C#:
DataTable dt = General.ImportDelimitedFile(file4import, delimiter, col_headers);
DataView f = dt.AsDataView();
dg.DataSource = f;
advantage = very quick load takes ~4 seconds (125mb in memory)
cons = very slow, on executing LINQ and when set visibility to rows
notes :
VS Error : Row associated with the currency manager's position cannot be made invisible
solution : dg.CurrentCell = null;
--
approach 1
add rows by hand :
C#:
List<DataGridViewRow> rows = new List<DataGridViewRow>(); //https://10tec.com/articles/why-datagridview-slow.aspx
while ((line = file.ReadLine()) != null)
{
if (line.Trim().Length > 0)
{
line = line.Replace("\"", "");
string[] cols = Regex.Split(line, delimiter, RegexOptions.Compiled);
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(this, cols);
rows.Add(row);
}
}
this.Rows.AddRange(rows.ToArray());
tried any possible variant apart List<T>, all of them had the same result.
advantage = LINQ and visibility to rows extremely fast
cons = takes ~12 seconds. (700mb in memory, even call SetProcessWorkingSetSize)
C#:
//Hidding rows in the DataGridView is too slow
//src - https://social.msdn.microsoft.com/Forums/windows/en-US/68c8b93e-d273-4289-b2b0-0e9ea644623a
public class DataGridViewEx : DataGridView
{
private bool m_Suspended = false;
public bool Suspended
{
get { return m_Suspended; }
set
{
if (m_Suspended != value)
{
m_Suspended = value;
if (!m_Suspended && this.Rows.Count > 0)
{
this.CurrentCell = null;
bool visible = this.Rows[0].Visible;
this.Rows[0].Visible = !visible;
this.Rows[0].Visible = visible;
}
}
}
}
protected override void OnRowStateChanged(int rowIndex, DataGridViewRowStateChangedEventArgs e)
{
if (!m_Suspended) base.OnRowStateChanged(rowIndex, e);
}
public void BeginUpdate()
{
this.Suspended = true;
DrawingControl.SuspendDrawing(this);
}
public void EndUpdate()
{
DrawingControl.ResumeDrawing(this);
this.Suspended = false;
}
public void ClearGrid(){
this.ClearSelection();
this.CurrentCell = null;
this.DataSource = null;
this.Rows.Clear();
this.Columns.Clear();
}
}
//////////////
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
internal static class DrawingControl
{ //https://stackoverflow.com/a/16625788
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
private const int WM_SETREDRAW = 11;
/// <summary>
/// Some controls, such as the DataGridView, do not allow setting the DoubleBuffered property.
/// It is set as a protected property. This method is a work-around to allow setting it.
/// Call this in the constructor just after InitializeComponent().
/// </summary>
/// <param name="control">The Control on which to set DoubleBuffered to true.</param>
public static void SetDoubleBuffered(Control control)
{
// if not remote desktop session then enable double-buffering optimization
if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
{
// set instance non-public property with name "DoubleBuffered" to true
typeof(Control).InvokeMember("DoubleBuffered",
System.Reflection.BindingFlags.SetProperty |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic,
null,
control,
new object[] { true });
}
}
/// <summary>
/// Suspend drawing updates for the specified control. After the control has been updated
/// call DrawingControl.ResumeDrawing(Control control).
/// </summary>
/// <param name="control">The control to suspend draw updates on.</param>
public static void SuspendDrawing(Control control)
{
SendMessage(control.Handle, WM_SETREDRAW, false, 0);
}
/// <summary>
/// Resume drawing updates for the specified control.
/// </summary>
/// <param name="control">The control to resume draw updates on.</param>
public static void ResumeDrawing(Control control)
{
SendMessage(control.Handle, WM_SETREDRAW, true, 0);
control.Refresh();
}
}
possible solution to use VirtualMode
Fast custom formulae, filtering and sorting in DataGrids
MS - Best Practices for Scaling the Windows Forms DataGridView Control
MS - Virtual Mode in the Windows Forms DataGridView Control