首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ColdFusion :单独请求终止CFTHREAD

ColdFusion :单独请求终止CFTHREAD
EN

Stack Overflow用户
提问于 2019-09-05 18:45:54
回答 3查看 568关注 0票数 4

我在我的ColdFusion应用程序中使用CFTHREAD。根据我从Ben (https://www.bennadel.com/blog/2980-terminating-asynchronous-cfthreads-in-coldfusion.htm)中读到的内容,ColdFusion只公开和跟踪当前请求中的线程。在我的情况下,我通过ajax调用生成一个线程,然后为用户提供一个cancel按钮。我希望cancel按钮能够调用线程上的终止方法,但是无论我在哪里存储它(应用程序、服务器、会话),ColdFusion总是返回一个错误,因为它无法终止线程"THREAD_NAME“,因为"THREAD_NAME”不是生成的。

我知道在幕后,ColdFusion主要是Java。所以我希望有办法。有人能确认或否认这种可能性吗?有怎样的例子吗?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-08 09:46:50

你能?

是的,但只使用内部类。创建cf线程时,使用本地THREAD_NAME检索对底层线程对象的引用。

代码语言:javascript
复制
context = getPageContext().getFusionContext();
thread = context.getUserThreadTask( "theLocalTaskName" );

由于本地名称可以被多个请求使用,所以引用应该存储在一个惟一的名称下,比如一个uuid。引用实际上是内部类coldfusion.threads.Task的一个实例。若要终止它,请调用其cancel()方法。

代码语言:javascript
复制
thread.cancel();

你应该吗?

这是一个很大的问题,这取决于线程做了什么--它是如何做的--以及如果进程在没有警告的情况下停止运行,那么它使用的资源将如何受到影响。

原因是调用<cfthread action="terminate"..>会立即杀死线程。CF并不关心它是否处于关键部分的中间。服务器只是用木槌敲打它,并阻止它冷却。异常日志显示CF是通过调用Thread.stop()来完成这一任务的。

“信息”、“cf线程-47”、"09/07/19“、"17:10:44”、"“、"THREAD_V_2:终止”在coldfusion.tagext.lang.ThreadTag.terminateThread(ThreadTag.java:345) at coldfusion.thread.Task.cancel的java.lang.ThreadDeath at coldfusion.thread.Task.cancel(Task.java:257)

java文档说stop()方法被废弃了,因为本质上是不安全的

停止线程会使其解锁其锁定的所有监视器。(当ThreadDeath异常在堆栈上传播时,监视器将被解锁。)如果以前受这些监视器保护的任何对象处于不一致状态,其他线程现在可能会以不一致的状态查看这些对象。据说这些物品被损坏了。当线程对损坏的对象进行操作时,可能会导致任意行为。这种行为可能是微妙的,很难发现,也可能是被宣布的。与其他未经检查的异常不同,ThreadDeath会默默地杀死线程;因此,用户不会警告他的程序可能已损坏。在实际损坏发生后的任何时候,甚至几个小时或几天后,损坏都可能出现。

因此,重要的是要考虑线程实际执行的任务,并确定终止线程是否安全。例如,如果一个线程使用FileOpen()处理一个文件,强制终止它可能会阻止线程释放句柄,使底层文件处于锁定状态,这是不可取的。

在java中停止线程的推荐方法是使用中断()。这本质上就是user12031119描述的概念。中断不会强行杀死线程。它只是一个指示线程停止处理的标志。让线程自己来决定何时退出是安全的。它允许线程在终止之前完成关键部分或执行任何清理任务。是的,它需要更多的编码,但结果比使用“终止”更稳定和更可预测。

票数 2
EN

Stack Overflow用户

发布于 2019-09-06 14:43:53

对不起,我没有50的声誉可以评论,所以我会把这个作为一个答复。最近,我与通过ajax生成的CFThread处于相同的情况,我需要以某种方式终止它,但无法终止。我在一个在应用程序范围内使用它的数据源的CFQuery中有一个CFLoop。因此,我想出的是登录到ColdFusion管理员并临时重命名数据源,这会导致线程抛出一个数据库错误。虽然这是不优雅的终止,但它达到了当时的目的。

所以在看到这个问题之后,它让我思考了一个可能的解决办法,如果没有一个已知的方法来完成这个任务。假设在线程处理期间,它测试应用程序/服务器/会话作用域中变量的值。假设该值最初设置为"true“,然后由另一个进程设置为" false”,则当线程找到false值时,它可以优雅地终止。

票数 3
EN

Stack Overflow用户

发布于 2019-09-06 20:46:10

您想要做的是设置一个数据结构,比如应用程序或会话范围,以跟踪您希望取消的线程的运行。

Application.cfc OnApplicationStart

代码语言:javascript
复制
<cfset application.cancelThread = {} />

在输入线程之前,创建id,然后传递给线程

代码语言:javascript
复制
<cfset threadId = createUUID() />
<cfset application.cancelThread[threadId] = false />

将threadId传递回客户端以获取“取消”按钮。单击“取消”按钮,将threadId发回

代码语言:javascript
复制
<cfset application.cancelThread[form.threadId] = true />

在线程执行期间

代码语言:javascript
复制
<cfif application.cancelThread[threadId]>
    <cfabort />
    <!--- or your chosen approach to ending the processing --->
</cfif>

如果线程到达终点,则删除线程引用。

代码语言:javascript
复制
<cfset structDelete(application.cancelThread, threadId) />
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57811387

复制
相关文章

相似问题

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