TC官方合作论坛

 找回密码
 立即注册
查看: 1492|回复: 11
打印 上一主题 下一主题

[已解决] 编辑框显示不同步

[复制链接]
跳转到指定楼层
楼主
发表于 2014-6-12 13:40:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上加入TC

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 贪吃蛇 于 2014-6-12 13:41 编辑

编辑框的 设置文本settext、下拉框的 增加文本addtext 都存在下例中的现象,标签的 设置文本settext无此现象:

例1:
功能 开始_点击()
    for(i=0;i<3;i++)
        
编辑框.设置文本("编辑框0",i)        
        help.sleep(1000)
    endfor
功能结束

期望结果:在编辑框0依次显示0、1、2;
实际结果:停顿后在在编辑框0只显示2,为什么看不到显示0、1?

例2:
功能 开始_点击()
    for(i=0;i<3;i++)
        
编辑框.设置文本("编辑框0",i)
        标签.设置文本("标签0",i)

        help.sleep(1000)
    endfor
功能结束

期望结果:在编辑框0和标签同时依次显示0、1、2;
实际结果:同期望结果,这个OK。

例3:
功能 开始_点击()
    for(i=0;i<3;i++)
        标签.设置文本("标签_主线程",i)

        编辑框.设置文本("编辑框0",i)
        help.sleep(1000)
    endfor
功能结束

期望结果:在编辑框0和标签同时依次显示0、1、2;
实际结果:标签显示0时编辑框无显示、标签显示1时编辑框显示0、标签显示2时编辑框显示1、标签停留在2编辑框显示2;只不过把例2中标签和编辑框两行互换了顺序,为什么编辑框总比标签慢1拍?



回复

使用道具 举报

9#
发表于 2014-6-12 14:34:14 | 只看该作者
贪吃蛇 发表于 2014-6-12 14:26
数据本身是正确的,已经用调试输出查看,问题出在把数据写到编辑框时不能及时显示,此时其它线程再从编辑 ...
  1. 功能 开始_点击()
  2.     线程.开启("测试.开启","")
  3. 功能结束
  4. 功能 开启()
  5.     for(i=0;i<10000;i++)
  6.         编辑框.设置文本("编辑框0",i)        
  7.         help.sleep(200)
  8.     endfor  
  9. 功能结束
  10. 功能 取_点击()
  11. 线程.开启("测试.取","")
  12. 功能结束
  13. 功能 取()
  14.     循环(真)
  15.         编辑框.设置文本("编辑框1",编辑框.获得文本("编辑框0"))
  16.     循环结束  
  17. 功能结束
复制代码


回复 支持 反对

使用道具 举报

沙发
发表于 2014-6-12 13:47:17 | 只看该作者
建议通过线程开启这些功能,应该就没问题了。因为功能里会导致界面无响应,所以你有可能看不到他改变后的结果。
回复 支持 反对

使用道具 举报

板凳
 楼主| 发表于 2014-6-12 13:59:25 | 只看该作者
frg0922 发表于 2014-6-12 13:47
建议通过线程开启这些功能,应该就没问题了。因为功能里会导致界面无响应,所以你有可能看不到他改变后的结 ...

线程也是在执行功能啊,这个问题就是因为我的多个线程用编辑框传递数据异常发现的,困惑哦
回复 支持 反对

使用道具 举报

地板
发表于 2014-6-12 14:01:54 | 只看该作者
本帖最后由 frg0922 于 2014-6-12 14:14 编辑

多个线程传递数据的话,要加临界区啊,不然会出问题的。单线程就不会。
线程执行功能可以防卡界面。和普通执行功能是不一样的。
回复 支持 反对

使用道具 举报

5#
发表于 2014-6-12 14:24:14 | 只看该作者
本帖最后由 续花丶 于 2014-6-12 14:26 编辑
  1. 功能 开始_点击()
  2. 线程.开启("测试.开启","")
  3. 功能结束
  4. 功能 开启()
  5. for(i=0;i<3;i++)
  6. 编辑框.设置文本("编辑框0",i)
  7. help.sleep(1000)
  8. endfor
  9. 功能结束
复制代码

一切正常。。不用线程 界面都卡死了。。你当然看不到 0  1
功能 开始_点击()
for(i=0;i<3;i++)
标签.设置文本("标签_主线程",i)  //先设置了标签,,你就会先看到标签变化
编辑框.设置文本("编辑框0",i)  //然后才是编辑框。
help.sleep(1000)
endfor
功能结束


回复 支持 反对

使用道具 举报

6#
 楼主| 发表于 2014-6-12 14:26:21 | 只看该作者
frg0922 发表于 2014-6-12 14:01
多个线程传递数据的话,要加临界区啊,不然会出问题的。单线程就不会。
线程执行功能可以防卡界面。和普通 ...

数据本身是正确的,已经用调试输出查看,问题出在把数据写到编辑框时不能及时显示,此时其它线程再从编辑框取数据就出错了。
问题抽取出来就是本帖例子所示的。
回复 支持 反对

使用道具 举报

7#
发表于 2014-6-12 14:29:31 | 只看该作者
不是说数据出问题了,是指多线程同时操作编辑框时,如果不加临界区的话,编辑框里的显示的数据就有可能会是错误的。所以你在编辑框操作前要加上临界区。
回复 支持 反对

使用道具 举报

8#
发表于 2014-6-12 14:33:19 | 只看该作者
本帖最后由 frg0922 于 2014-6-12 14:40 编辑

临界区模式
临界区是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问如果有多个线程试图同时访问临界区,那么在有一个线 程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的。



临界区在使用时以系统结构对象保护共享资源,并分别用 线程.进入临界区()或thread.entercritical()和线程.离开临界区()或者thread.leavecritical()函数去标识和释放一个临界区所用到的系统结构对象必须经过 线程.创建临界区()或者thread.createcritical()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能而且在程序不需要或退出的时候,必须调用 线程.删除临界区()或thread.deletecritical()释放临界区如下图所示:



线程A和线程B执行到临界区时,系统会随机选择谁先进入临界区(一般规则是谁先到临界区,谁先进入临界区,若是同时到,那么就系统随机分配),只要一方进入临界区,那么另一方就得等待,知道进入的线程离开临界区,系统才允许等待的线程才会进入临界区。



在使用临界区时,一般不允许其运行时间过长,只要进入临界区的线程还没有离开,其他所有试图进入此临界区的线程都会被挂起而进入到等待状态,并会在一定程度上影响程序的运行性能尤其需要注意的是不要将等待用户输入或是其他一些外界干预的操作包含到临界区如果进入了临界区却一直没有释放,同样也会引起其他线程的长时间等待换句话说,在执行了 线程.进入临界区() 语句进入临界区后无论发生什么,必须确保与之匹配的 线程.离开临界区()都能够被执行到虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。



举例:

2个线程向一个记事本输入内容,在存在临界区的情况,输入的数据很有条例和顺序但是在没有临界区的情况下,输入的数据就乱套了大家可以动手试试。
  1. 空间 临界区测试
  2. 对象句柄 = 0
  3. 功能 喊话(内容)
  4. 句柄集1 = 系统.枚举("Notepad",1) // 使用1个记事本测试
  5. 如果(字符串.长度(句柄集1) == 0)
  6. 辅助.消息框("没有找到窗口")
  7. 返回 -1
  8. 如果结束
  9. // 通过父窗口获取子窗口
  10. 句柄集2 = 系统.枚举(句柄集1,3)
  11. 如果(字符串.长度(句柄集2) == 0)
  12. 辅助.消息框("没有找到窗口")
  13. 返回 -1
  14. 如果结束
  15. // 分割子窗口字符型句柄
  16. 变量 子句柄字符串数组
  17. 字符串.分割(句柄集2,"|",子句柄字符串数组)
  18. 变量 长度=0,序号=0
  19. 变量 句柄
  20. 数组空间.大小(子句柄字符串数组,长度)
  21. // 来确认我们的子窗口是我们需要子窗口
  22. 循环(序号 < 长度)
  23. 如果(窗口.类名(子句柄字符串数组[序号]) == "Edit")
  24. 句柄= 子句柄字符串数组[序号]
  25. 跳出
  26. 如果结束
  27. 序号 = 序号 + 1
  28. 循环结束
  29. 遍历(5)
  30. 线程.进入临界区(对象句柄)
  31. 窗口.提交按键(句柄,13) // 按一次回车键
  32. 辅助.等待(100)
  33. 窗口.提交字符串(句柄,内容) // 向窗口发送内容
  34. 辅助.等待(100)
  35. 窗口.提交按键(句柄,13) // 把内容发送出去
  36. 线程.离开临界区(对象句柄)
  37. 遍历结束
  38. 返回 0
  39. 功能结束
  40. 功能 执行()
  41. 对象句柄 = 线程.创建临界区()// 初始化临界区
  42. 线程句柄1= 线程.开启("临界区测试.喊话","123456789")
  43. 线程句柄2= 线程.开启("临界区测试.喊话","abcdefg")
  44. 线程.等待(线程句柄1,60*1000)//最长等待线程句柄1的线程执行1分钟
  45. 线程.等待(线程句柄2,60*1000)//最长等待线程句柄2的线程执行1分钟
  46. 线程.删除临界区(对象句柄) // 释放临界区
  47. 调试输出("程序执行完毕")
  48. 功能结束
  49. 空间结束
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

10#
发表于 2014-6-12 18:59:57 | 只看该作者
姐们,我只想说= =系统的消息处理线程被你用作等待了- -界面当然不会更新。。。
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18043773号

GMT+8, 2025-9-26 18:00 , Processed in 0.247052 second(s), 24 queries .

Powered by 海安天坑软件科技有限公司

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表