Вывести на экран сообщение о завершении последнего потока

Поддержка
  • Как при запуске стандартного многопотока отследить завершение последнего потока и выполнить по окончанию определенное действие? Например вывести сообщение на экран или скопировать обработанный файл.

    1. Можно сделать одну какую-то функцию и в нее поместить все действия
    2. Вызвать ее действием "Вызов функции в многопоточном режиме" в функции Main
    3. Учитывать что в действии "Вызов функции в многопоточном режиме" обычные переменные будут не доступны для скрипта, поэтому чтобы передавать данные можно использовать действие "глобальные переменные"

    Может есть варики получше как сделать, если разбираться

  • Хотелось бы малой кровью обойтись, чтобы не переделывать старые скрипты. Сейчас глобальной переменной контролирую опустошение списка записей из первого потока, на экран посылаю сообщение об окончании, но скрипт полностью еще не завершен, т.к. эта процедура не в самом конце выполняется. А хотелось чтобы выполнить процедуру действительно в самом конце. Возможно можно добавить каждому потоку асинхронный поток для контроля, но пока не придумал как сделать.

  • @vladdr
    Есть в BAS API есть такой метод:

    _finnaly(function(){
     log("END");
    })
    

    если выполнить такой код в начале потока то callback
    будет вызываться перед завершением потока success/fail.

  • Спасибо. Я попробовал код, и каждый поток выполняет этот код в конце потока. Но мою задачу до конца не решило. Мне нужно чтобы последний работающий поток выполнил это действие. Но уже хорошо, тут по крайней мере можно в глобальные переменные передавать инфу о закрытии конкретного потока, а дальше обработать.

  • @vladdr Глобальные переменные придется в любом случае использовать.
    Эта функция помогает сделать всю обработку в 1 кубике (в начале потока)

  • @vladdr

    PSet("basglobal", "THREADS", parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) + parseInt(1))
    
    _finnaly(function(){ 
     var t = parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) - parseInt(1);
     PSet("basglobal", "THREADS", t)
     if (t == 0) {
        log("LAST THREAD");
     }
    })
    
  • Очень полезный скрипт, спасибо. Но мне так и не удалось реализовать мою задачу. Мне всего-навсего нужно было выполнить , например получить сообщение на экран командой винды msg /SERVER:WIN-6A3MK3B9UJJ * "Парсинг закончился". Если я допустим запускаю вручную кусок кода, то я получаю сообщение на экран и вывод логов. А если я запускаю в составе потоков, лог последний получаю правильно, а сообщение не получаю.
    Вот скрипт с частью кода запуска "Запустить процесс", без него не выполнялся внешний процесс.
    // Увеличиваем счетчик потоков
    PSet("basglobal", "THREADS", parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) + parseInt(1))

    _finnaly(function(){
    // Уменьшаем счетчик потоков
    var t = parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) - parseInt(1);
    PSet("basglobal", "THREADS", t);

    // Если это последний поток
    if (t == 0) {
        // 1. Уведомление в BAS
        log("Парсинг закончился");
        log("LAST THREAD");
        
        // 2. Системное уведомление Windows
        // Создаем временный BAT файл
        var batFile = "temp_msg_" + Date.now() + ".bat";
        var command = 'msg /SERVER:WIN-6A3MK3B9UJJ * "Парсинг закончился"';
        
        // Записываем BAT файл
        native("filesystem", "writefile", JSON.stringify({
            path: batFile,
            value: "@echo off\r\nchcp 65001 > nul\r\n" + command,
            base64: false,
            append: false
        }));
        
        // Запускаем процесс
        native_async("processmanager", "start", JSON.stringify({
            location: batFile,
            working_folder: "",
            waitfinish: true,
            arguments: "",
            version: 2
        }))!;
        
        // Очищаем временный файл
        sleep(500)!;
        native("filesystem", "removefile", batFile);
    }
    

    })

  • @vladdr said in Вывести на экран сообщение о завершении последнего потока:

    native_async

    нет поддержки вызова асинхронных функций.

    если скопировать модуль processmanager и сделать вызов "Синхронным" работать будет.
    ProcessesSync.zip

    PSet("basglobal", "THREADS", parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) + parseInt(1))
    
    _finnaly(function () { 
      var t = parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) - parseInt(1);
      PSet("basglobal", "THREADS", t)
       if (t == 0) {
          log("LAST THREAD");
          RANDOM_FILE = "temp_" + rand() + ".bat"
          native("filesystem", "writefile", JSON.stringify({path: RANDOM_FILE,value: "chcp 65001\r\n" + (("".length>0) ? ("cd " + "" + "\r\n") : "" ) + (("msg /SERVER:WIN-6A3MK3B9UJJ * \u0022Парсинг закончился\u0022").replace(/\r?\n/g, "\r\n")),base64:false,append:false}))
          log(RANDOM_FILE);
          var s = native("processmanager_sync", "start", JSON.stringify({location: RANDOM_FILE, working_folder: "", waitfinish: true, arguments: "", version: 2}))
          var ss = s.split(",");
          for (var k in ss) {
            log(base64_decode(ss[k]));
          }
          native("filesystem", "removefile", RANDOM_FILE);
        }
    })
    

    ff418da7-24fd-4cec-8557-0ca2cb45f6b8-image.png

  • @Int64 said in Вывести на экран сообщение о завершении последнего потока:

    если скопировать модуль processmanager

    можно не копировать, а пропатчить оригинал: \apps\29.6.0\modules\Processes\manifest.json

      "exportlist": [
        {
          "name": "start",
          "isasync": true,
          "waitinfinite": true,
          "workfunction": "ProcessManagerRunExe"
        },
        {
          "name": "start_sync",
          "isasync": false,
          "waitinfinite": true,
          "workfunction": "ProcessManagerRunExe"
        }
      ]
    
    

    и используем:

    native("processmanager", "start_sync", JSON.stringify({location: RANDOM_FILE, working_folder: "", waitfinish: true, arguments: "", version: 2}))
    
  • This post is deleted!
  • Спасибо за помощь, все получилось. Последний вариант не очень понял как использовать, использовал предпоследний вариант.

  • Случилась авария, скорее всего после обновления(движок-29.6.1). Не находиться функция: Поток завершился с сообщением "Failed to find function processmanager_sync.start". Поэтому перестало выдаваться сообщение.

  • Проблему удалось решить следующим образом. Получилось даже лучше.
    Создаем отдельную функцию, например передачу сообщения в телегу, а далее в приведенный выше код вставляем вызов этой функции, например _call_function(SOOBSCHENIE_TELEGA,{})!;
    Получился такой скриптик:

    PSet("basglobal", "THREADS", parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) + parseInt(1))

    _finnaly(function(){
    var t = parseInt(JSON.parse(P("basglobal", "THREADS") || "0")) - parseInt(1);
    PSet("basglobal", "THREADS", t)
    if (t == 0) {
    log("LAST THREAD");
    _call_function(SOOBSCHENIE_TELEGA,{})!;
    }
    })