Lucee/ColdFusion用thread检测邮件端口时THESERVERS不存在报错
问题原因与修复方案
核心错误点
- 线程参数引用错误:启动线程时传入的属性为
theDomains、theNames,线程内部读取传入参数必须使用Attributesscope,原代码中使用不存在的domains变量调用检测接口,导致方法执行失败未生成返回值。 - 线程返回值存储scope错误:线程内部的
VARIABLESscope为线程私有,外部无法访问,需要对外传递的返回值必须存入Threadscope。 - 输出逻辑变量引用错误:输出循环中
ATTRIBUTES.theNames指向的是当前页面/函数的属性域,不存在对应变量,服务器名称需要提前存储或存入线程返回域中。 - Lucee线程读取规则差异:Lucee环境无法直接通过
cfthread[]读取线程对象,需使用threadData()函数获取线程数据。
修正后代码
RetrieveEmailServers = APPLICATION.selectQueries.RetrieveEmailServers() if (RetrieveEmailServers.recordCount) { // 提前存储所有服务器信息,方便输出时读取 LOCAL.serverList = [] for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) { LOCAL.serverList[i] = { domain = RetrieveEmailServers.check_servers_domain[i], name = RetrieveEmailServers.check_servers_name[i] } // 启动线程时传入域名参数 thread action="run" name="thread#i#" checkDomain="#LOCAL.serverList[i].domain#" { // 线程内部用Attributes取传入的参数,返回结果存入Thread scope对外暴露 Thread.checkResult = APPLICATION.emailCheck.checkSMTPServer(Attributes.checkDomain,25,'',''); } } // 等待所有线程执行完成 thread action="join" timeout="6000"{} // 遍历输出结果 for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) { // Lucee环境用threadData()获取线程对象 VARIABLES.threadObj = threadData()["thread#i#"] // 判断检测结果生成状态标识 if (VARIABLES.threadObj.checkResult) { LOCAL.theStatus = "<i class='fad fa-angle-double-up text-success fs-1'></i>" } else { LOCAL.theStatus = "<i class='fad fa-angle-double-down text-danger fs-1'></i>" } // 从提前存储的serverList中取服务器名输出 writeOutput(LOCAL.serverList[i].name & " - " & LOCAL.theStatus & "<br>"); } } else { writeOutput("No servers listed at this time.") }
线程Scope快速说明
Attributesscope:线程内部只读,存储启动线程时传入的所有参数Threadscope:线程内部可写、外部可读,专门用于存放需要传递到线程外的返回数据- 线程内的
VARIABLESscope:仅线程内部可访问,外部无法读取
内容的提问来源于stack exchange,提问作者Grimdari
相关产品推荐
相关产品推荐

