yon*_*236 7 c# .net-2.0 winforms
美好的一天!
我想就此事提出您的建议.
我正在办公室里制作一个小工具,将"产品层次结构数据"显示在树形视图中.我们的应用程序只能以表格方式显示它,如果层次结构中存在任何不正确的数据,则会使其难以跟踪.
我能够制作一些逻辑并以正确的层次结构显示数据.
但我这里的主要问题是我正在处理100K-200K +记录,它确实需要时间来制作/分配每个节点并将其添加到树中.从我的测试中,每分钟创建的平均节点数为8000.我还注意到该应用程序的内存使用量随着运行而逐渐增加.
我将包括数据结构的截图以及应用程序的外观,以便您了解一下:


请考虑下面的代码,我将非常高兴知道您对如何优化此代码的想法.我知道这里有很多需要改进的地方.
抱歉长篇大论......
顺便说一下,我正在使用C#和.net2.0.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data;
using System.IO;
using System.Threading;
namespace WinformAppTest
{
public partial class MainForm : Form
{
private DataSet _ds = new DataSet();
public MainForm()
{
InitializeComponent();
}
void MainFormLoad(object sender, EventArgs e)
{
PopulateDataSet();
lblTotalRows.Text = _ds.Tables[0].Rows.Count.ToString();
}
void PopulateDataSet()
{
string query = @"select * from " + "test.csv";
try
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\;Extended Properties=\"Text;HDR=Yes;FMT=Delimited\"");
OleDbDataAdapter da = new OleDbDataAdapter();
OleDbCommand cmd = new OleDbCommand(query, conn);
conn.Open();
da.SelectCommand = cmd;
_ds.Clear();
da.Fill(_ds, "CSV");
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.GetBaseException().ToString());
}
}
void BtnRunClick(object sender, EventArgs e)
{
Thread newThread1 = new Thread(MainForm.DoWork);
newThread1.Start(this);
}
public static void DoWork(object data)
{
MainForm form = (MainForm)data;
int counter = 0;
TreeNode[] nd;
foreach(DataRow row in ((MainForm)data)._ds.Tables[0].Rows)
{
TreeNode node = new TreeNode();
if(row["Level Number"].ToString() == "1")
{
node.Name = row["ECC Hierarchy Code"].ToString();
node.Text = row["ECC Hierarchy Code"].ToString() + ", " + row["Name"].ToString();
form.Invoke((MethodInvoker)delegate { ((MainForm)data).treeView1.Nodes.Add(node); });
}
else
{
nd = ((MainForm)data).treeView1.Nodes.Find(row["Parent Code"].ToString(), true);
node.Name = (string)row["ECC Hierarchy Code"];
node.Text = row["ECC Hierarchy Code"].ToString() + ", " + row["Name"].ToString();
form.Invoke((MethodInvoker)delegate { nd[0].Nodes.Add(node); });
}
counter++;
form.Invoke((MethodInvoker)delegate { ((MainForm)data).lblLoded.Text = counter.ToString(); });
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
关键可能如下:
这将停止添加/删除节点时发生的任何绘制.一旦调用了EndUpdate,整个TreeView就会被绘制一次.
http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.beginupdate.aspx
内置的 WinForms 控件在处理大型数据集时受到限制。据我记得,内置的 TreeView 将尝试为每个节点分配它自己的内存(这意味着对于 100K+ 条记录中的每条记录,您都有一份数据副本以及附加元数据,即使其中大多数记录不会被删除)在给定会话中查看。
我使用提供虚拟节点的开源 TreeView 替代方案取得了很大的成功(在它们变得可见之前不会渲染)
http://www.codeproject.com/Articles/20552/Virtual-Treeview-Implementation