Показать сообщение отдельно
Старый 20.01.2021, 14:49   #40  
kair84 is offline
kair84
Участник
 
47 / 58 (2) ++++
Регистрация: 15.04.2010
Адрес: Belarus
Цитата:
Сообщение от mazzy Посмотреть сообщение
canRunInNewSession можно использовать только для обработок, которые не используют файлы. с этой штукой class File не работает.
Прошу прощения за офтоп, и за то что поднял эту старую тему.
Как мне кажется она не потеряла своей актуальности.

У меня как раз возникла проблема, после длительной операции, более 10 мин, нужно вернуть пользователю файл с данными. Чтобы сессия не отвалилась в обычный RunBaseBatch класс был добавлен метод canRunInNewSession = true. и действительно в методе Run класс File отказывается работать. Нигде не нашел подсказок как обойти это, только благодаря этой ветке это стало возможным.

Делюсь опытом возможно кому то пригодиться: в Run методе после того как закончилось заполнение объекта файла, *StreemIO в моем примере или любого другого файла, содержимое файла необходимо перегнать в строковую переменную которая участвует в Pack/Unpack. Затем, после выполнения RunOperation вызвать код отправки файла пользователю.

X++:
class Test_RunbaseBatch extends RunBaseBatch
{
    // Packed variables
    str             csvFileContent;

    #define.CurrentVersion(1)
    #localmacro.CurrentList
        csvFileContent
    #endmacro

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

    public void run()
    {
        if (! this.validate())
            throw error("");

        commaStreamIo iO = commaStreamIo::constructForWrite();

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

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

            // sleep(1000); //Over 10 min.
            sleep(100);
        }

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

    }

    public void runAfterOperation()
    {
        Filename filename = "file.csv";
        File::SendStringAsFileToUser(csvFileContent,  filename, System.Text.Encoding::Unicode);
        info(strFmt("CSV file %1 Sent to user",filename));
    }

    public boolean runsImpersonated()
    {
        return true;
    }

    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";
    }

    static Test_RunbaseBatch construct()
    {
        return new Test_RunbaseBatch();
    }

    static void main(Args args)
    {
        Test_RunbaseBatch    runBase;

        runBase = Test_RunbaseBatch::construct();

        if (runBase.prompt())
        {
            runBase.runOperation();
            runBase.runAfterOperation();
        }

    }

    protected boolean canRunInNewSession()
    {
        return true;
    }

}

Последний раз редактировалось kair84; 20.01.2021 в 15:04.
За это сообщение автора поблагодарили: Vadik (1), trud (2).