在 cfloop 中使用 cfthread 会导致随机输出

Using cfthread inside cfloop results in random output

我在 ColdFusion 中有一个循环遍历应用程序 ID 列表的例程。在该列表中,发生了很多事情,包括 PDF 文档的生成和合并。这变得非常慢,所以我看了一下 cfthread 可以为我做什么。结果很有希望; 40 秒 运行 时间缩短为 4 秒。

但是,cfthread 就其性质而言,不知道循环在做什么。这是一个代码示例。

<cfloop list="#form.User_Id#" index="x">
    <cfthread name="thread#x#" action="run" index="#x#">
          <cfdocument format="PDF" name="report" filename="#fileToDownload#" overwrite="yes">
          <cfdocumentsection>
          <cfquery name="example" datasource="DS">
             SELECT * FROM Table
             WHERE ID = #x#
          </cfquery>

          <cfoutput query="example">
               All the output
          </cfoutput>
          </cfdocumentsection>
    </cfthread>
</cfloop>

<cfthread action="join" />

最终发生的是每次循环迭代都会重复列表中的最后一个值。那么我到底需要做什么才能使这项工作正常进行呢?

谢谢!

可能像 Adam 所说的那样需要更多。

如果您在这里寻找 "end result",您的 "final PDF" 取决于 loop/thread 代码所做的工作,上面的代码将给你不一致和不可预测的结果。

另请注意,上面的代码有可能根据列表的长度创建任意数量 的线程。它将创建这些线程 - 正如您所注意到的 - "fire and forget" - 让他们同时做他们的事情。你需要做的是弄清楚 A) 你需要多少线程或你的系统可以处理然后 B) 设计你的循环以便你 terminatejoin 你的线程适当。这样他们就成为了这个请求的一部分,而不仅仅是在主请求完成后一些任意的工作工具。

Ray (Camden) 在他的博客上有一个很好的例子,他循环 10 次然后将它们全部连接在一起。如果您的代码经常或同时运行(您可能会超出线程请求限制),这可能不可行,但可能是计划任务的正确方法。这是 Ray 文章的 link。

http://www.raymondcamden.com/2009/05/18/CFTHREAD-When-to-join

您可以谨慎地思考 "chunks" 使您的线程选择可预测的工作。例如,在您的循环中,您最多可以创建 5 个线程,然后在第 5 次迭代中 join 它们,第 6 次迭代将开始下一次分组……明白我的意思了吗?