aardio传递到C#中DataTable显示大量数据的优化办法
如题:
之前有写过几个调用dataGridView来显示数据表格的示例,
测试发现如果直接for循环一句一句add会很慢. 代码如下:
//创建随机数据 dataTable.BeginLoadData(); for(i=1;50000;1){ row = dataTable.NewRow(); //第一种方式 row.Item["RowIndex"] = i; row.Item["StringColumn"] = string.random(5); row.Item["DecimalColumn"] = 3.1415 / (i + 1); row.Item["BooleanColumn"] = (math.random(1,10)%2==0)?true:false; //第二种方式 //row.ItemArray = {i, string.random(5),3.1415 / (i + 1) ,(math.random(1,10)%2==0)?true:false}; dataTable.Rows.Add(row); } dataTable.EndLoadData();
可以测试发现, 如果数据非常大的时候显示就会非常慢 ,
我猜测可能是因为每次和c#传递和交换数据aardio都要封包解包导致.
知道原因后, 就可以写个dll来直接传递aar中的table表到c#程序集中, 这样速度就可以达到和c#中使用一样的速度了.
代码如下:
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=759;bottom=469) winform.add( custom={cls="custom";text="自定义控件";left=0;top=0;right=760;bottom=470;bgcolor=12639424;db=1;dl=1;dr=1;dt=1;z=1} ) /*}}*/ import console console.open() import System.Windows.Forms; var Forms = System.Windows.Forms; var dataGridView = Forms.CreateEmbed("DataGridView",winform.custom); dataGridView.ColumnHeadersHeightSizeMode = 2; //避免在高分屏下错乱 import System.Type; import System.Data; var Data = System.Data; var dt =Data.DataTable("DT"); //定义列格式 var integerColumn = Data.DataColumn("RowIndex",System.Type.GetType("System.Int32")); var stringColumn = Data.DataColumn("StringColumn",System.Type.GetType("System.String")); var decimalColumn = Data.DataColumn("DecimalColumn",System.Type.GetType("System.Decimal")); var boolColumn = Data.DataColumn("BooleanColumn",System.Type.GetType("System.Boolean")); //绑定格式 dt.Columns.Add(integerColumn); dt.Columns.Add(stringColumn); dt.Columns.Add(decimalColumn); dt.Columns.Add(boolColumn); //填充大量数据 var data={} for(i=1;50000;1){ data[i] = { i, "Txt"+i,math.random(), math.round(math.random()*10)%2?true:false }; } //-------------------------------------------------------- //转换aardio的table表到c#的List表 var listdata = dotNet.createArrayList(data); //引用数据传递dll var convertdll = dotNet.load("\ListTodataTable.dll"); var Table = convertdll.import("ListTodataTable.Table");//Create //写入list数据到DataTable Table.WriteTo(dt,listdata); //------------------------------------------------------ //显示数据 var dataView = System.Data.DataView(dt); dataGridView.DataSource = dataView; dataGridView.EditMode=2; winform.show(); win.loopMessage();
可以看到无论多大的数据量,上面速度都回来了.5W数据从创建界面到显示完成只需要2秒.
ListTodataTable.dll程序集和测试工程如下:
下面将c#生成这个dll程序集的代码分享如下:
using System; using System.Collections; using System.Data; namespace ListTodataTable { public class Table { public static void WriteTo(DataTable dataTable , object args ) { ArrayList list = (args as ArrayList); dataTable.BeginLoadData(); for (int i = 0; i < list.Count; i++) { DataRow dataRow = dataTable.NewRow(); var dlist = (list[i] as Array); for (int j = 0; j < dlist.Length; j++) { dataRow[j] = dlist.GetValue(j); } dataTable.Rows.Add(dataRow); } dataTable.EndLoadData(); } } }
鉴于还有人问怎么内嵌dotnet的程序集dll到exe里 , 生成独立绿色的exe:
使用dotnet.reference()功能即可.
比如: 针对我上面那个数据ListTodataTable.dll 示例, 你把用到的dll放到工程的res目录里然后调用即可, 完整的内嵌代码工程如下:
import win.ui; /*DSG{{*/ mainForm = win.form(text="aardio工程4";right=868;bottom=522;bgcolor=15780518) mainForm.add() /*}}*/ import console console.open() import dotNet; import System.Windows.Forms; var Forms = System.Windows.Forms; var dataGridView = Forms.CreateEmbed("DataGridView",mainForm); dataGridView.ColumnHeadersHeightSizeMode = 2; //避免在高分屏下错乱 import System.Type; import System.Data; var Data = System.Data; var dt =Data.DataTable("DT"); //定义列格式 var integerColumn = Data.DataColumn("RowIndex",System.Type.GetType("System.Int32")); var stringColumn = Data.DataColumn("StringColumn",System.Type.GetType("System.String")); var decimalColumn = Data.DataColumn("DecimalColumn",System.Type.GetType("System.Decimal")); var boolColumn = Data.DataColumn("BooleanColumn",System.Type.GetType("System.Boolean")); //绑定格式 dt.Columns.Add(integerColumn); dt.Columns.Add(stringColumn); dt.Columns.Add(decimalColumn); dt.Columns.Add(boolColumn); //填充大量数据 var data={} for(i=1;50000;1){ data[i] = { i, "Txt"+i,math.random(), math.round(math.random()*10)%2?true:false }; } //-------------------------------------------------------- //转换aardio的table表到c#的List表 var listdata = dotNet.createArrayList(data); //引用数据传递dll dotNet.reference({ ["ListTodataTable.Table"] = "\res\ListTodataTable.dll"; }) var Table = dotNet.import("ListTodataTable.Table");//Create //写入list数据到DataTable Table.WriteTo(dt,listdata); //------------------------------------------------------ //显示数据 var dataView = System.Data.DataView(dt); dataGridView.DataSource = dataView; dataGridView.EditMode=2; mainForm.show(); return win.loopMessage();
可以看到内嵌dotnet程序集dll的关键代码:
//引用数据传递dll dotNet.reference({ ["ListTodataTable.Table"] = "\res\ListTodataTable.dll"; }) var Table = dotNet.import("ListTodataTable.Table");//Create //写入list数据到DataTable Table.WriteTo(dt,listdata);
所以, 如果你调用了多个程序集dll , 都可以用上面的方式 ,reference()里是一个表, 你可以插入任意多个dll声明..
注意这个方式是专门针对 c#的程序集dll.
需要内嵌的文件放入到了res目录里同步目录后, 后面使用就不需要加$符号, 其他目录的话需要加$内嵌资源到工程里.
登录后方可回帖
正在为这个速度的事苦恼,刚好您来了...
我也想直接写dll,没付出行动...
谢谢