Показать сообщение отдельно
Старый 27.01.2021, 12:52   #47  
kair84 is offline
kair84
Участник
 
47 / 58 (2) ++++
Регистрация: 15.04.2010
Адрес: Belarus
Вижу что тема Вам не сильно интересна, хотя казалось что даже очень.
Чтоб закрыть её, вот как можно сделать прогресс для обычного RunBase :

X++:
class Test_RunBaseBatch extends RunBaseBatch
{
    DialogField     dfDuration;

    // Packed variables
    int             duration;
    str             csvFileContent;
    Email           email2Send;
    guid            callId;


    #define.CurrentVersion(1)
    #localmacro.CurrentList
        callId,
        duration,
        csvFileContent,
        email2Send
    #endmacro

    SysOperationProgressWait progressWait;
    //SysProgress sysProgress;

    public object dialog()
    {
        DialogRunbase dialog;

        dialog = super();

        dfDuration = dialog.addFieldValue(identifierStr(Integer),duration,"Duration (Sec.)");


        return dialog;
    }

    public boolean getFromDialog()
    {
        boolean ret;

        ret = super();

        duration = dfDuration.value();

        email2Send = SysUserInfo::getUserEmail(curUserId());

        return ret;
    }

    public container pack()
    {
        return [#CurrentVersion,#CurrentList];
    }

    public void runAsync()
    {
        callId = newGuid();
        progressWait = SysOperationProgressWait::construct();
        progressWait.parmCallId(callId);
        progressWait.parmCaption(this.caption());
        progressWait.parmBatchTaskId(0);


        xGlobal::runAsyncWithObjectCallback(
            classNum(Test_RunBaseBatch),
            staticMethodStr(Test_RunBaseBatch, doRunAsync),
            this.pack(),
            this, methodStr(Test_RunBaseBatch, runAsyncCallback));
        
        Message::Add(MessageSeverity::Informational ,"Start Operation Async");

        progressWait.beginWaiting();
    }

    private void runAsyncCallback(AsyncTaskResult _result)
    {
        progressWait.endWaiting();

        Message::Add(MessageSeverity::Informational ,"End Operation Async");

        container parms = _result.getResult();
        this.unpack(parms);
        this.runAfterOperation();

    }

    private static container doRunAsync(container _parms, System.Threading.CancellationToken cancellationToken)
    {
        Test_RunBaseBatch runbase = new Test_RunBaseBatch();
        runbase.unpack(_parms);
        runbase.run();
        return runbase.pack();
    }

    public void run()
    {
        Message::Add(MessageSeverity::Informational ,"run");

        if (! this.validate())
        throw error("");

        SysOperationProgressServer progressBar = new SysOperationProgressServer(1,false,callId);
        progressBar.setCaption("SysOperationProgressServer !!!");
        progressBar.setTotal(duration);



        commaStreamIo iO = commaStreamIo::constructForWrite();

        container header = ["Num"];
        iO.writeExp(header);

        int i;
        for (i=1; i<=duration; i++)
        {
            iO.write(i);

            progressBar.incCount();
            progressBar.setText(strFmt("%1 / %2",i,duration));

            sleep(1000);
        }

        
        System.IO.Stream stream = iO.getStream();
        stream.Position = 0;
        System.IO.StreamReader reader = new System.IO.StreamReader(stream);
        csvFileContent = reader.ReadToEnd();

        if (this.isInBatch())
        {
            this.runAfterOperation();
        }

        Message::Add(MessageSeverity::Informational ,"Done!");

    }

    public void runAfterOperation()
    {
        info("runAfterOperation");

        Filename filename = "file.csv";
        System.Byte[] byteArray =  System.Text.Encoding::Unicode.GetBytes(csvFileContent);
        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
        stream.Position = 0;

        if (this.isInBatch())
        {
            if (SysEmailDistributor::validateEmail(email2Send))
            {
                SysMailerMessageBuilder messageBuilder = new SysMailerMessageBuilder();
                messageBuilder.setFrom(email2Send,"@SYS115063")
                            .addTo(email2Send)
                            .setPriority(1)
                            .setSubject(this.caption())
                            .setBody(this.caption())
                            .addAttachment(stream, fileName);
                SysMailerFactory::sendNonInteractive(messageBuilder.getMessage());
                info(strFmt("CSV file %1 Sent to user on e-mail %2",filename,email2Send));

            }
        }
        else
        {
            File::SendFileToUser(stream, fileName);
            info(strFmt("CSV file %1 Sent to user",filename));
        }

    
    }

    public boolean unpack(container packedClass)
    {
        Version version = RunBase::getVersion(packedClass);
        ;
        switch (version)
        {
            case #CurrentVersion:
                [version,#CurrentList] = packedClass;
                break;
            default:
                return false;
        }

        return true;
    }

    public boolean validate(Object _calledFrom = null)
    {
        if (false)
        return checkFailed("");

        return true;
    }

    static ClassDescription description()
    {
        return "Test RunBase Descr.";
    }

    static void main(Args args)
    {
        Test_RunBaseBatch    runBase;

        runBase = new Test_RunBaseBatch();
        runBase.init();

        if (runBase.prompt())
        {
            runBase.runAsync();
        }

    }

    protected boolean canRunInNewSession()
    {
        return false;
    }

}

Очевидно, что для того, чтобы во время выполнения кода на сервере была возможность взаимодействовать с пользователем, необходимо выполнять операцию асинхронно, а для того, чтобы связать серверный процесс с интерфейсом стали использовать таблицу SysProgress, в нее пишется вся необходимая информация о прогрессе (один или несколько прогресс-баров, заголовок, текст, и т.д) и обновляется в время выполнения.

Надеюсь проделанная мной работа не напрасна и пригодится кому то еще кроме меня. Возможно даже удостоится переноса в Блог.
За это сообщение автора поблагодарили: trud (10).