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

Mr_MAO 7月前 785

循环语句(for,while)有break、continue关键字可以跳出循环,有没有什么关键字可以暂停(pause)循环呢?

问了下AI,说fiber纤程可以,试了下,真的可以实现暂停、恢复循环语句的功能。

下面给个演示的示例(也是比较常用的一个应用场景):

Code AardioLine:109复制
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
    • 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 7月前
      0 2
      学习了,感谢分享。你以前在另外的论坛的贴子(已关闭了)能不能重新在这里面再分享一下,谢谢!
    • Mr_MAO 7月前
      0 3
      shzhbook 学习了,感谢分享。你以前在另外的论坛的贴子(已关闭了)能不能重新在这里面再分享一下,谢谢!
      我也没有存档,那是去年有段时间学aar时发的帖子,内容基本忘掉了,需要哪方面资料我们可以私聊。
    返回