为何CFTHREAD在循环中复用局部变量值?
循环创建CFTHREAD时变量值被覆盖的问题
在循环中创建CFTHREAD时,所有线程似乎都在使用最后一次循环的变量值,而非创建线程时的当前值。相关伪代码如下:
LOCAL.Items=[ "ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ" ]; for (LOCAL.item in LOCAL.Items) { writeoutput(LOCAL.item & "<br />"); } for (LOCAL.item in LOCAL.Items) { thread name="items-#LOCAL.item#" action="run" { writelog(text=LOCAL.item, type="information", file="thread-test"); } }
第一个循环的输出符合预期:
ABC DEF GHI JKL MNO PQR STU VWX YZ
但thread-test.log中的日志显示大部分条目都是最后一个值"YZ":
"Information","cfthread-23","03/11/24","13:18:40","MNO" "Information","cfthread-28","03/11/24","13:18:40","YZ" "Information","cfthread-23","03/11/24","13:18:40","YZ" "Information","cfthread-28","03/11/24","13:18:40","YZ" "Information","cfthread-23","03/11/24","13:18:40","YZ" "Information","cfthread-28","03/11/24","13:18:40","YZ" "Information","cfthread-23","03/11/24","13:18:40","YZ" "Information","cfthread-28","03/11/24","13:18:40","YZ" "Information","cfthread-23","03/11/24","13:18:40","YZ"
问题根源
这是因为CFTHREAD是异步执行的,线程内部引用的LOCAL.item是循环变量的引用,而非创建线程时的副本。当线程真正开始执行时,循环可能已经完成或者走到了后续迭代,此时LOCAL.item的值已经被更新为循环后期甚至最后一次的值。
解决方案
需要将当前迭代的LOCAL.item作为线程的属性参数传递进去,这样每个线程会获得独立的变量副本,不会受循环变量后续变化的影响。修改后的代码如下:
LOCAL.Items=[ "ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ" ]; for (LOCAL.item in LOCAL.Items) { writeoutput(LOCAL.item & "<br />"); } for (LOCAL.item in LOCAL.Items) { thread name="items-#LOCAL.item#" action="run" currentItem=LOCAL.item { writelog(text=attributes.currentItem, type="information", file="thread-test"); } }
关键修改点:
- 在
thread标签中添加currentItem=LOCAL.item,将当前迭代的值作为线程属性传递 - 线程内部通过
attributes.currentItem访问该值,确保拿到的是创建线程时的当前值,而非循环变量的引用
内容的提问来源于stack exchange,提问作者Eric Belair
相关产品推荐
相关产品推荐

