循环语句(for,while)有break、continue关键字可以跳出循环,有没有什么关键字可以暂停(pause)循环呢?
问了下AI,说fiber纤程可以,试了下,真的可以实现暂停、恢复循环语句的功能。
下面给个演示的示例(也是比较常用的一个应用场景):
import win.ui;
var formtilte = "文件复制工具:用fiber纤程控制暂停";
/*DSG{{*/
var winform = win.form(text=formtilte;right=759;bottom=303)
winform.add(
button1={cls="button";text="选择源文件";left=48;top=40;right=198;bottom=90;z=1};
button2={cls="button";text="设置目标文件夹";left=48;top=120;right=198;bottom=170;z=2};
button3={cls="button";text="复制文件";left=48;top=200;right=198;bottom=250;z=3};
progress={cls="progress";left=208;top=208;right=712;bottom=238;max=100;min=0;z=4};
static={cls="static";text="Static";left=208;top=40;right=712;bottom=88;center=1;transparent=1;z=5};
static2={cls="static";text="Static";left=208;top=120;right=712;bottom=168;center=1;transparent=1;z=6}
)
/*}}*/
//引用的库
import fsys;
import fsys.safepath;
import fsys.dlg;
import fsys.dlg.dir;
//全局变量
var sourceFile = "";
var targetFolder = "";
var copyFiber = null;
var isPaused = false;
winform.button1.oncommand = function(id, event){
var path = fsys.dlg.open( "All Files (*.*)|*.*","选择源文件");
if(path){
sourceFile = path;
winform.static.text = path;
winform.progress.pos = 0;
targetFolder = "";
winform.static2.text = "";
}else {
sourceFile = "";
}
}
winform.button2.oncommand = function(id, event){
if(sourceFile=="") return;
var path = fsys.dlg.dir( ,,"选择目标文件夹");
if(path){
targetFolder = path;
winform.static2.text = path;
winform.progress.pos = 0;
winform.button3.text = "复制文件";
}else {
targetFolder = "";
}
}
var copyFile = function(){
if(sourceFile=="") return; if(targetFolder=="") return;
var totalSize = io.getSize(sourceFile);
var copiedSize = 0;
var chunkSize = 1024 * 1024; // 1MB
var buffer = raw.buffer(chunkSize);
var file1 = io.open(sourceFile, "r+b");
var targetPath = fsys.safepath( targetFolder ++ "\" ++ fsys.getFileName(sourceFile) ) ;
var file2 = io.open(targetPath, "w+b");
file1.seek("set")
while(true){
var readlen = file1.readBuffer(buffer);
if(readlen){
file2.writeBuffer(buffer, readlen);
copiedSize += readlen;
winform.progress.pos = (copiedSize / totalSize) * 100;
winform.text = formtilte ++ " (" ++ winform.progress.pos ++ "%)";
win.peekPumpMessage(1);
} else {
break;
}
//控制暂停复制(只能在for语句中yield)
if(isPaused){
winform.button3.text = "继续复制";
fiber.yield();
}
}
file1.close();
file2.close();
sourceFile = "";
targetFolder = "";
winform.text = formtilte
winform.button3.text = "复制文件"
winform.msgbox("文件复制完成!","结果");
}
winform.button3.oncommand = function(id, event){
//使用纤程调用复制函数
if(fb_copyfile){
isPaused = !isPaused; //切换
if(isPaused==false){
owner.text = "暂停复制";
fiber.resume(fb_copyfile); //恢复纤程,继续复制
}
}else {
isPaused = false;
owner.text = "暂停复制";
fb_copyfile = fiber.create(copyFile); //创建纤程,并引用函数
fiber.resume(fb_copyfile); ////使用纤程调用函数
}
}
winform.show();
win.loopMessage();
记住,只能在纤程的create()方法参数1的函数体中用yield()方法暂停循环,不能在外部暂停循环。只能在循环体外用resume()方法恢复循环。
一知半解,平时很少接触纤程,与同好者共勉,见笑了