aardio传递到C#中DataTable显示大量数据的优化办法

By admin at 2022-04-19 • 1人收藏 • 1660人看过

如题:

之前有写过几个调用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();

image.png

可以看到无论多大的数据量,上面速度都回来了.5W数据从创建界面到显示完成只需要2秒.

ListTodataTable.dll程序集和测试工程如下:

ListTodataTable.zip



下面将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();
        }
    }
}


6 个回复 | 最后更新于 2022-05-18
2022-04-20   #1

正在为这个速度的事苦恼,刚好您来了...

我也想直接写dll,没付出行动...

谢谢

2022-05-10   #2

鉴于还有人问怎么内嵌dotnet程序集dllexe里 , 生成独立绿色的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目录里同步目录后, 后面使用就不需要加$符号, 其他目录的话需要加$内嵌资源到工程里.



2022-05-17   #3

运行测试代码,不显示check列
image.png
是我哪里弄错了?

2022-05-17   #4

回复#3 @money :

如果打包的示例运行没问题,就是你代码有问题。aar范例里也有datalistview示例,也可以运行看看

2022-05-17   #5

我用示例没问题

2022-05-18   #6

找到原因了
dataGridView.AutoSizeRowsMode  = 11/*DisplayedCells*/ //修正部分高分屏下不显示复选框
谢谢各位

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...