Foxtable(狐表)用户栏目专家坐堂 → [求助]多线程的问题


  共有5541人关注过本帖树形打印复制链接

主题:[求助]多线程的问题

帅哥哟,离线,有人找我吗?
有点蓝
  31楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:106209 积分:540168 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2019/2/22 8:37:00 [只看该作者]

如果历史月份的数据是不变的,为什么不计算后直接保存下来呢。以后直接查询就行了,不需要再去计算。如果以后发现这个月数据有问题,需要修复,修复后再重新计算一次就行了

 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  32楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2195 积分:18043 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2019/2/23 15:17:00 [只看该作者]

蓝版主,把所有的数据按调整、入库每个月都存一个最新值然后按需要调用,有一些其它的问题暂时不好解决(数据库的调整影响比较大),暂时不想动它了,还是用后台SQL查询来解决,多列多线程查找赋值,用的时间可能比直接取用时间长一点,再想其它的办法吧。现在多线程专业问题请教。

比如说在全局代码中定义一个线程“XC001”
Public Sub XC001(ByVal cr As Object,ByVal s As Object)
    functions.Execute("JS01", cr,s)
End Sub


然后在自定义函数中定义一个函数“JS01”
dim r as row = args(0)
dim s as integer = args(1)
dim dt as datatable
c m d . C o n n e c t i o n N a m e   =   " P M "
cmd.CommandText = "外部连接数据库SQL"
dt = cmd.ExecuteReader()
Return dt   ‘函数运行的结果返回dt

那么开启多线程该怎么整?象下面这样
vars("数量1计算完成")  = false
Dim t1 As Threading.Thread =  New Threading.Thread(AddressOf XC01)
t1.Start(r,1)
vars("数量1计算完成")  = true

'同理计算数量2
vars("数量2计算完成")  = false
Dim t2 As Threading.Thread =  New Threading.Thread(AddressOf XC02)
t2.Start(r,2)
vars("数量2计算完成")  = true

if vars("数量1") = true andalso vars("数量2") = true  then 
'执行代码,因为这段代码要利用数量1和数量2的计算结果
end if 

但是,启动线程之后希望得到函数的计算结果(就是return dt的那个dt),应当怎么做呢
[此贴子已经被作者于2019/2/23 15:42:36编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点蓝
  33楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:106209 积分:540168 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2019/2/23 16:54:00 [只看该作者]

如果要使用线程的返回结果,只能是把结果放到全局变量中,无法直接使用函数的返回指的。把dt赋值给全局变量

 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  34楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2195 积分:18043 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2019/2/24 21:45:00 [只看该作者]

蓝版主,实际测试的情况是,开启两个线程分别计算调整值和已入库值,在商品目录是4万行时,用时几乎就是秒杀。
反而是把这4万行的数据赋值到界面上的速度慢。实际测试赋三列的值用时近7秒钟。
我看到帮助里的“查询与赋值并存”说1万行赋值约0.8秒,看来也就是这个效率了。

看来还得想其它的招来解决计算结果赋值的问题。
而且,赋值完成以后,还有递归计算的工作要处理。性能优化,任重道远啊。

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  35楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2019/2/24 21:49:00 [只看该作者]

 

具体问题,请做一个对应实例发上来测试。

 

 


 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  36楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2195 积分:18043 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2019/3/12 22:35:00 [只看该作者]

1、常规做法,我的示例中已经做了。也能实现功能。但是在数据量大的情况下,速度慢,比如要做5列的数据赋值,光执行SQL都要10秒左右,这个我自己都受不了,更别说用户了。
2、蓝版主,不能拿这个示例来就事论事。因为现在的系统不是单一功能,也没法把整个系统都传到这里,只是借这个示例来说明一下,如何来提高效率(包括SQL计算、赋值,用多线程处理或者存储过程处理是否能优化,或者用临时表、临时列、数据冗余等等)

主要意图如下:
1、点TbAlter的行,打开模式窗口AlterD,在窗口中把在本次调整日期之前调整过的量显示出来,然后填写本次的调整量
2、点TbRK的行,打开模式窗口RKD,在窗口中把本次入库日期之前已经调整过的量、之前已经入库过的量显示出来,然后填写本次入库的数量、单价、其它费用

在数据量大的时候,第二步时,如果逐一执行SQL赋值,用时会比较长;如果要计算4列或5列的值就会更长(这里可能开启多线程会减少一部分时间)

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:多线程处理大量数据.zip



[此贴子已经被作者于2019/3/12 22:38:09编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  37楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2019/3/13 10:06:00 [只看该作者]

看了一下,你直接用异步函数处理,就可以啊

 

http://www.foxtable.com/mobilehelp/scr/3269.htm

 

执行sql语句,可以多线程的,但对dr的赋值,有可能多线程会冲突,具体请自行测试。

 

你给的实例无法测试你说的耗时的问题,请做对应的实例发上来


 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  38楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2195 积分:18043 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2019/3/13 20:38:00 [只看该作者]

异步函数不能操作界面表数据,只能操作后台数据,所以,是否用异步函数对上面的示例来说似乎并无太大意义,因为可以开启多线程直接执行SQL并赋值给全局代码中定义的表(例如示例的DTRKD)。

然后接下来就是将DTRKD中的值赋值给界面表了。帮助里也说了,多线程不能操作界面表,所以赋值只以依次执行了,这个时间估计很难优化。除非利用其它的方法,不用字典。

至于实例无法测试耗时,如果我把物资目录搞到几万行,然后做个十期八期调整记录、再做个几十期入库明细,那数据就太大,论坛都不让上传了。
所以,实际数据可以用随机函数,增加多期数据来测试。
[此贴子已经被作者于2019/3/13 20:38:09编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点甜
  39楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 帖子:85326 积分:427815 威望:0 精华:5 注册:2012/10/18 22:13:00
  发帖心情 Post By:2019/3/13 20:58:00 [只看该作者]

1、你赋值的时候,如果冲突,那你就用同步函数处理

 

http://www.foxtable.com/mobilehelp/scr/3270.htm

 

2、如果你思路不变,那是没办法的优化的。用异步函数,你可以在后台执行,不影响你前台的其它操作,你慢慢等它完成即可

 

3、不清楚你的逻辑,你可以处理数据都在后台数据表啊,最后一次性把数据加载显示出来即可。


 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  40楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2195 积分:18043 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2019/3/13 21:28:00 [只看该作者]

不清楚你的逻辑,你可以处理数据都在后台数据表啊,最后一次性把数据加载显示出来即可
----这个就象前面的示例。
比如说我想在办理入库的时候,已知它们的初始计划数量A,但同时想知道各种物资截止目前为止的调整数量B(它来源于tbAlterD),同时想知道它截止上次入库为止已经入库的数量C(它来源于TbRKD表),这样才能办理入库(因为要求入库的数量不能超计划,也就是本次入库的数量必须不能大于A+B-C)

象你所说的在后台数据表,是说全局代码表,还是后台的数据库实体表呢?
如果是全局代码表还好一点,要是数据库实体表要实时保存B和C,涉及到多人同时操作时,可能会有不可预知的麻烦,比如说数据同步计算错误,甚至会不会导致数据库死锁。

基于这种考虑,我才想着在客户端动态计算B和C值,虽然也有可能导致多人同时操作时会有违背这个业务规则的数据发生,但可以有数据统计功能向用户提示这种非法数据。这样也免去了频繁更新后台数据的情况。冗余有一定的好处,但这种情况下冗余的设计可能并不是个好方案

至于赋值的数据冲突,应当不会有太大的问题。因为B列和C列的数据来源于不同的表,而且全局代码表设了两个,分别来做B和C所需的值的计算,在统计和赋值上应当不会有冲突。


其实,我也想过用一个全局代码表X,让它执行SQL,合并B和C的统计,这个SQL比较复杂了,什么left join之类的嵌套一堆看得我眼晕,然后界面表的源就直接设为X,然后加载,但实际效率不理想,因为数据量太大了,本身SQL执行的速度就不快。

后来考虑了一种方案,就是把物资按它们所属的分类整成树,点击树节点的时候,就只加载这个节点(以及它的所有子节点)的物资,这样,计算量会明显小很多。比如说物资分为10类,就算每一类有4000种,也比一次性计算和加载4万行要快得多。

本来按我的想法,物资明细搞个两三千行就已经很大了,没想到用户搞出来的明细数量将近10万行(我一看就几乎晕倒),想让用户搞简化一点,用户不接受,没办法,只能照办
[此贴子已经被作者于2019/3/13 21:43:14编辑过]

 回到顶部
总数 59 上一页 1 2 3 4 5 6 下一页