搜索
查看: 242|回复: 2

多线程操作richedit控件,退出慢的问题请教

[复制链接]

12

主题

38

帖子

236

积分

新手入门

积分
236
发表于 2018-9-11 20:33:40 | 显示全部楼层 |阅读模式
    如下所示的代码,在界面中单击按钮停止后,界面卡死几秒钟,然后console打印"线程停止失败",去掉thrdTest线程中的 winform.richedit.appendText("停了!"),然后再测试就正常了,请大家帮我解惑,增加 winform.richedit.appendText("停了!") 这句代码,为什么console会打印"线程停止失败",谢谢!
  1. import win.ui;
  2. /*DSG{{*/
  3. var winform = win.form(text="aardio form";right=479;bottom=235)
  4. winform.add(
  5. button={cls="button";text="Start";left=132;top=14;right=324;bottom=56;z=1};
  6. richedit={cls="richedit";left=4;top=66;right=476;bottom=232;edge=1;multiline=1;z=2}
  7. )
  8. /*}}*/

  9. import console;

  10. var thrdHandle = null;
  11. thrdTest = function(winform){
  12.                 import console;
  13.                
  14.                 winform.richedit.text = "";
  15.                
  16.                 /*
  17.                 thread.lock创建一个临界区,
  18.                 在多线程中同时只能有一个线程进入相同名字的临界区,
  19.                 这是为了避免同时访问同一资源,例如大家都争着去写控制台,你写几个字符,他写几个字符,结果写出来谁也看不懂了。
  20.                 aardio中需要用临界区的时候并不多,因为每个线程都有自己的变量环境不会相互冲突,很少需要去加锁考虑同步这些麻烦的问题。
  21.                 */
  22.                 thread.lock("写控制台",function(){
  23.                         console.log("线程在执行",thread.getId())
  24.                 })
  25.                
  26.                 /*
  27.                 thread.get用于访问线程共享变量。
  28.                 每个线程的全局变量环境都是独立的,而 thread.get() 则用于获取所有线程共享的全局变量。
  29.                 */
  30.                 while(!thread.get("红灯停")){ //这里如果高级点可以用 thread.event来实现信号判断,参考本目录下的定时器范例
  31.                         console.log("线程在执行",time() )
  32.                         winform.richedit.appendText("线程在执行" ++ '\r\n');
  33.                         sleep(1000)
  34.                 }
  35.                
  36.                 winform.richedit.appendText("停了!");
  37.                 console.log("停了!");
  38. }

  39. winform.button.oncommand = function(id,event){
  40.     if ("Stop" == winform.button.text) {
  41.                 //每个线程的全局变量环境都是独立的,而 thread.set() 则用于设置所有线程共享的全局变量。
  42.                 thread.set("红灯停", true)
  43.                
  44.                 /*
  45.                 等待所有线程完成,下面的参数可以是一个或多个线程句柄,也可以是包含多个线程句柄的数组。
  46.                 这个函数是阻塞并等待所有线程完成,如果是只等待某个线程返回,则需要使用 thread.waitOne()
  47.                 thread.waitOne() 如果在界面线程中他不会阻塞界面的消息循环( 就是还能响应用户对界面的操作,而不是卡住没响应 )
  48.                 */
  49.                 if (true != thread.waitAll(thrdHandle, 5000)) {
  50.                         console.log("线程停止失败!");
  51.                 }
  52.                
  53.                 thread.set("红灯停", null)
  54.                
  55.                 //句柄不用的时候一定要用下面的函数关闭(切记:句柄是绝对不会自动释放的),关闭句柄并不会关闭线程
  56.                 raw.closehandle(thrdHandle)
  57.                
  58.                 winform.button.text = "Start";
  59.         } else {
  60.                 thrdHandle = thread.create(thrdTest, winform);
  61.                 winform.button.text = "Stop";
  62.         }
  63. }

  64. winform.show();
  65. win.loopMessage();
  66. return winform;
复制代码


回复

使用道具 举报

185

主题

2541

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
13973
发表于 2018-9-11 21:11:28 | 显示全部楼层
答案都已经写好了,你自己都复制到你的帖子里了,
有时间发帖子打字,没时间看一下自己的代码?!现在提问成本这么低了吗?!

都写的清清楚楚 thread.waitAll 会暂停界面线程,
然后你还在界面线程锁死的情况下,给界面线程发消息,
这相当于把对方的嘴堵上,来来来,我们聊完了再让你说话。跟电脑也要讲理的,不然程序怎么可能正常。






回复

使用道具 举报

12

主题

38

帖子

236

积分

新手入门

积分
236
 楼主| 发表于 2018-9-11 22:14:45 | 显示全部楼层
Jacen.He 发表于 2018-9-11 21:11
答案都已经写好了,你自己都复制到你的帖子里了,
有时间发帖子打字,没时间看一下自己的代码?!现在提问 ...

谢谢Jacen,不好意思,打扰了。

将thread.waitAll修改为thread.waitOne就可以了,再次感谢Jacen!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

手机版|未经许可严禁引用或转载本站文章|站长邮箱|aardio.com|aardio官方社区 ( 皖ICP备09012014号 )

GMT+8, 2018-10-21 22:38 , Processed in 0.046875 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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