首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CFTHREAD中的作用域问题

CFTHREAD中的作用域问题
EN

Stack Overflow用户
提问于 2012-11-13 01:49:22
回答 2查看 1.2K关注 0票数 1

我有一个应用程序,每晚发送几个100k的电子邮件,所以为了加快处理速度,添加了一些cfthread。

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

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

代码语言:javascript
复制
<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,正如我所期望的那样。

有人知道这是怎么回事吗?

EN

回答 2

Stack Overflow用户

发布于 2012-11-13 04:01:52

我相信你运行cfthread的目的是错误的。看起来线程2中的tmpEmailBody依赖于thread1。您不应该在单独的线程中运行依赖代码。

与邮件相关的cfthread更好的用法可能是

Thread1 {从a-m列表中选择以a-m开头的数据库中的电子邮件}

线程2{从数据库中选择电子邮件,其中电子邮件从n-z开始}从你的列表中选择n-z}

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

票数 0
EN

Stack Overflow用户

发布于 2012-11-13 06:58:32

变量tmpEmailBody是在Variables作用域中创建的,而不是在限于线程的作用域中创建的。线程将以随机顺序和随机时间执行,因此导致错误的原因是,在thread2执行其第一行之前,thread1尚未执行其最后一行。

在使用cfthread时,所有普通作用域都不是线程安全的(而不是对ColdFusion请求线程而言是线程安全的;又称页面线程)如果您希望确保在一个线程中创建/使用的变量与所有其他线程隔离,则必须使用线程作用域。这在ColdFusion文档中被正式记录为Using thread data

我会猜到你在两个线程之外声明了tmpEmailBody,但是因为将cfset改为静态字符串会产生预期的行为,所以我会说cfsavecontent有一个“问题”,它写入的是Variables作用域,而不是线程本地作用域,后者应该被归档为another scoping gotcha

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

代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13348767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档