|
26.01.2021, 18:06 | #1 |
Участник
|
C asyncCallbackReturnValue(..) разобрался, это баг в стандартном методе SysOperationServiceController.asyncCallbackReturnValue(..). Колбэк возвращаяет одну переменную, значит второй параметр нужно сделать необязательным.
Вот так все хорошо, и _returnValue имеет правильное значение, ровно то что вернул метод сервиса. X++: ... public void asyncCallbackReturnValue(AsyncTaskResult _asyncResult, anytype _returnValue = _asyncResult.getResult()) { info(strFmt("Async Callback Result: %1",con2Str(_returnValue))); //super(_asyncResult,_returnValue); //Box::info("Async Callback Result Box"); } ... Последний раз редактировалось kair84; 26.01.2021 в 18:14. |
|
|
За это сообщение автора поблагодарили: madm (1). |
27.01.2021, 12:52 | #2 |
Участник
|
Вижу что тема Вам не сильно интересна, хотя казалось что даже очень.
Чтоб закрыть её, вот как можно сделать прогресс для обычного 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). |