在扩展设置中使用异步方法调用子程序时,获取返回值困难

使用问题 · 67 次浏览
白云朔 创建于 5天23小时前

主程序

【多字段表单】

【A字段】(字符串)单行文本输入框

【B字段】(字符串)单行文本输入框(只读)

扩展设置:compute:$= _context.RunSpAsync("子程序",new { 传入值 = _context.GetVariables() })

子程序

【子程序】

【子程序输入】{传入值}

【赋值】{传入值}["A字段"] -> {返回值}

(实际应用场景中可能存在更多复杂操作,这里为便于理解仅使用赋值)

【子程序输出】{返回值}

 

对于【B字段】中的异步调用方法,字段始终只会显示:

System.Threading.Tasks.Task`1[System.Collections.Generic.IDictionary`2[System.String,System.Object]]

 

而如果直接对

_context.RunSpAsync("子程序",new { 传入值 = _context.GetVariables() })

使用 ["Result"]["返回值"] 来取值,会提示:

无法将带[]的索引应用于“Task<IDictionary<string,object>>”类型的表达式

并在运行时报错。

 

目前测试下来只找到两种方法来获取【多字段表单】中异步调用的子程序的返回值的方法:

1.结束当前【多字段表单】窗口运行,通过【赋值】模块运行$= _context.RunSpAsync("子程序",new { 传入值 = _context.GetVariables() })并输出到词典变量上,并对该词典进行索引取值。但是此方法必须在每次输入后打断当前窗口界面,体验感极差。

2.相对较好的方法,在子程序中的结尾写入一个动作状态"返回值",然后添加一个新的“字段C”并使用compute:$= _context.ReadState("返回值","")来获取返回值。但是这也会存在问题,由于字段C只能在其他字段更新时同步更新,如果子程序功能耗时过长,会导致字段C只能读取到未更新的状态,导致刷新存在一步的延迟。

具体案例及已尝试解决方法可详见:异步调用取值测试 - by 白云朔 - 动作信息 - Quicker

以及坚持使用异步方法调用子程序,而不是 $= _context.RunSp() ,主要是为了避免子程序运行时间过长而阻塞【多字段表单】窗口输入,导致卡顿。并且用于适配异步调用子程序的“节流阀”子程序也已完成,异步方法可能导致的高频触发大量线程导致性能浪费的问题也以基本解决。现在主要就卡在了获取返回值这一点上了。
个人也跟AI拉锯了好几天,得到的解决方案大多都会导致【多字段表单】窗口的输入被阻塞,试下来也只有在子程序中更新动作状态或者主程序变量比较可行,但是都一样会遇到刷新时机的问题。

所以想问一下C大,是否有办法在多字段表单中获取到异步调用的子程序的返回值呢?或者是否有办法在子程序中完成动作状态写入后通知或触发多【多字段表单】窗口刷新呢?

白云朔 最后更新于 2025/10/29

回复内容
CL 5天5小时前
#1

😂

你的问题有点太高深了,超出功能设计的预期,以及我还有点理解不了。

这种可能需要长时间返回的,可能需要上一级代码本身以异步方式调用自定义程序。 或者使用某种回调机制。

目前的设计只能处理一些简单情况,估计不太行。

白云朔 回复 CL 5天3小时前 :

主要问题就是多字段表单里的表达式形式似乎都不支持异步的回调,常规的几种方法,要么是用不了,要么是会导致窗口线程卡死。

个人这边测试下来,通过动作状态来返回子程序参数是最稳妥且稳定的,但是由于子程序完成计算并写入状态之后,多字段表单窗口未触发刷新,导致字段内的取到的状态值仍然会停留在上一步。


所以综合下来,这边想请问C大,是否有办法在子程序中触发指定窗口的刷新呢?或者让多字段表单像自定义操作窗一样,可以通过窗口标识来在子程序中直接覆盖式刷新呢?(参考HDG大佬之前给自定义操作窗做的一个demo:Demo:动态更新操作窗外观 - by H-D-G - 动作信息 - Quicker

白云朔 最后更新于 5天3小时前
回复主贴