1

我有一个应用程序,每晚发送几封 10 万封电子邮件,因此为了加快处理速度,添加了一些 cfthreads。

这导致了一些奇怪的错误,我发现在一个线程中创建的变量正在被另一个线程修改。从我读过的文档中,在一个线程中创建的变量应该只对该线程可见?

做了一个简单的测试,如下所示:

<cfthread
    name="thread1"
    action="run">

    <cfsavecontent variable="local.template_body">
        <cfinclude template="templates\6\2\bulletin_template.cfm">
    </cfsavecontent>

    <cfset tmpEmailBody = template_body>
</cfthread>

<cfthread
    name="thread2"
    action="run">

    <cffile action="append"
            file="C:\inetpub\error1.txt"
            output="#tmpEmailBody#">        
</cfthread>

“tmpEmailBody”的内容成功写入文件。

奇怪的是,如果我删除了 cfsavecontent 部分,并且有: <cfset tmpEmailBody = "test">,那么第二个线程会引发错误,并且 tmpEmailBody 没有定义,正如我所期望的那样。

有人知道这里发生了什么吗?

4

2 回答 2

0

我相信您运行 cfthread 的目的是错误的。似乎线程 2 中的 tmpEmailBody 依赖于线程 1。您不应该在单独的线程中运行相关代码..

更好地使用与邮件有关的 cfthread 可能是

Thread1 {从数据库中选择电子邮件,其中电子邮件从您的列表中开始 }

线程 2 { select Emails from database where emails start from nz} out your list nz }

您的两个线程同时运行。这 2 个查询可以同时发生,但您不能在 1 个线程中保存变量并希望它与您在另一个线程中的调用时间相匹配。

于 2012-11-12T20:01:52.033 回答
0

该变量tmpEmailBody是在Variables范围内创建的,而不是在仅限于线程的范围内。线程将以随机顺序和随机时间执行,因此导致错误是因为在执行第一行thread1之前尚未执行最后一行。thread2

使用 cfthread 时,所有正常范围都不是线程安全的(与 ColdFusion 请求线程的线程安全相反;又名页面线程)如果您想确保在一个线程中创建/使用的变量与所有其他线程隔离,那么您必须使用线程范围。这在 ColdFusion 文档中被正式记录为使用线程数据。

我猜想您是tmpEmailBody在两个线程之外声明的,但是由于将 cfset 更改为静态字符串会产生预期的行为,我会说存在“问题”,cfsavecontent并且它正在写入Variables范围而不是线程本地范围,这应作为另一个范围界定问题提交。

由于 ColdFusion 文档示例还有一些不足之处,因此我将重写您的代码,就好像您想将电子邮件正文从一个线程传递到另一个线程一样。您已经说过这不是您的预期用途,但它会显示各种线程范围。以下代码在不需要时将值复制到不同的范围内,但这样做是为了希望使不同的范围更清晰。而且,正如其他人所说,以下任务是线程使用不当。

<cfthread
    name="thread1"
    action="run">

    <cfset var template_body = "">

    <cfsavecontent variable="template_body">
        <cfinclude template="templates\6\2\bulletin_template.cfm">
    </cfsavecontent>

    <cfset thread.tmpEmailBody = template_body>
</cfthread>

<cfthread action="join" name="thread1" timeout="60">

<cfset Variables.tmpEmailBody = cfthread["thread1"]tmpEmailBody>

<cfthread
    name="thread2"
    action="run"
    emailBody="#Variables.tmpEmailBody#">

    <cffile action="append"
            file="C:\inetpub\error1.txt"
            output="#Attributes.emailBody#">        
</cfthread>
于 2012-11-12T22:58:31.583 回答