![]() |
#36 |
Участник
|
Вижу что тема Вам не сильно интересна, хотя казалось что даже очень.
Чтоб закрыть её, вот как можно сделать прогресс для обычного 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). |