如何暂停(pause)循环语句?

Mr_MAO 9天前 231

循环语句(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()方法恢复循环。

一知半解,平时很少接触纤程,与同好者共勉,见笑了


最新回复 (2)
  • shzhbook 9天前
    0 2
    学习了,感谢分享。你以前在另外的论坛的贴子(已关闭了)能不能重新在这里面再分享一下,谢谢!
  • Mr_MAO 8天前
    0 3
    shzhbook 学习了,感谢分享。你以前在另外的论坛的贴子(已关闭了)能不能重新在这里面再分享一下,谢谢!
    我也没有存档,那是去年有段时间学aar时发的帖子,内容基本忘掉了,需要哪方面资料我们可以私聊。
返回