在工作线程中直接操作界面控件固然令人愉快,
但如果代码量一大,界面与逻辑混杂在一起,会让代码不必要的变的千头万绪复杂臃肿。
如果把多线程比作多条轨道上并列飞奔的火车,那么火车交互的方法不仅仅只有停下来同步,或者把手伸出车窗来个最直接的亲密交互。一种更好的方式是拿起手机给隔壁火车上的人打个电话 - 发个消息,或者等待对方操作完了再把消息发回来。
这种响应式的编程方式在aardio里就是 thead.command,下面我们看一个简单的例子:
import win.ui;
var winform = win.form(text="线程命令";right=599;bottom=399)
winform.add(edit={cls="edit"; ...})
import thread.command;
var listener = thread.command();
listener.print = function( ... ){
winform.edit.print( ... ) //我们在界面线程中这样响应工作线程的消息
}
thread.invoke( //创建工作线程
function(){
import thread.command; //必须在线程函数内部导入需要的库
thread.command.print("hello world",1,2,3); //调用界面线程的命令
}
)
winform.show();
win.loopMessage();
thread.command可以把多线程间复杂的消息交互伪装成普通的函数调用,非常的方便。
这里新手仍然可能会困惑一点:我在工作线程中不是可以直接操作界面控件么?! 你这个thread.command虽然好用,但是多写了不少代码呀。
这样去理解是不对的,你开个轮船去对象菜市场买菜固然是有点麻烦,但如果你开轮船去环游世界那你就能感受到它的方便在哪里了。thread.command 一个巨大的优势是让界面与逻辑完全解耦,实现界面与逻辑的完全分离,当你的程序写到后面,代码越来越多,就能感受到这种模式的好处了。
例如 aardio自带的自动更新模块的使用示例代码:
import fsys.update.dlMgr;
var dlMgr = fsys.update.dlMgr(
"http://update.aardio.com/api/v1/version.txt","/download/update-files")
dlMgr.onError = function(err,filename){
//错误信息 err,错误文件名 filename 这里可以不用做任何处理,因为出错了就是没有升级包了
}
dlMgr.onConfirmDownload = function(isUpdated,appVersion,latestVersion,description){
if( ! isUpdated ){
//已经是最新版本了
}
else {
//检测到最新版本,版本号 latestVersion
};
return false; //暂不下载
}
dlMgr.create();
这个fsys.update.dlMgr里面就用到了多线程,但是他完全不需要直接操作界面控件。
而你在界面上使用这个对象的时候,你甚至都完全不用理会他是不是多线程,不会阻塞和卡死界面,有了结果你会收到通知,你接个电话就行了压根不用管他做了什么或者正在做什么。
这个fsys.update.dlMgr里面就是使用thread.command实现了实现界面与逻辑分离,你可以把检测、下载、更新替换并调整为不同的界面效果,但是fsys.update.dlMgr的代码可以始终复用。
主题数 10 | 今日评论 0 | 今日主题 0 |