我有一些冗长而复杂的代码可以进行一些解析,需要一段时间才能完成,在这种情况下优化代码没有多大意义。
处理长执行时间并让用户知道何时完成的策略是什么?
解释为什么优化
没有多大意义该应用程序具有面向最终用户的页面和面向非最终用户的页面。在非面向用户的区域,我正在解析几个excel电子表格。加载和循环这些需要很长时间。我优化代码在我今天可能工作的超时限制内运行,但是从现在起一个月我可能会导入一个4倍长的文件,它将无法再次运行。我试图解决的问题是绕过我知道需要很长时间的特定操作的cf超时。
我尝试过使用线程,但由于某种原因在CF9上工作但不支持CF8(虽然它们受到支持)
我也刚刚发现了cfsetting requestTimeOut
可能能够做我需要做的事情。
答案 0 :(得分:2)
你可能已经调查过了,但看看是否可以缓存任何内容,以减少等待的时间。
至于将其传达给用户,对于初学者来说,确保用户知道事情何时发生。程序可以做的最糟糕的事情之一就是接收输入而不做出反应。确保用户在发生任何事情时都很清楚。显示加载的方式取决于您。如果加载时间大约在10秒左右,可能会出现沙漏,但如果等待时间较长,您可能需要进度条或类似的东西。
如果有任何方法可以允许其中一些在后台或其他过程中发生,这可能有助于减轻负载。否则,弹出一个告诉他们去喝咖啡的建议。 :)
这只是一个只有少量信息的膝盖反应,但是如果你可以更多地了解你正在寻找的东西和粗略的加载时间估计,我可能会更具体。
答案 1 :(得分:1)
我在II6和CF 7上有一个网站。我添加了这个通过Javascript操纵的条形图。然后我会通过Javascript后跟<cfflush>
来设置图表的长度。
在网站升级到II7.5和CF 9之前一直运行良好。由于某种原因<cfflush>
不起作用,Javascript仍然可以设置标准并提供有意义的进展。
这需要两个iframe。
一个iframe运行长时间运行的进程,并在用户视图中隐藏。
另一个iframe运行的页面每10秒左右刷新一次。此页面查询后端日志记录以查找缓慢的进程。它可能落后10秒,但最终用户甚至可能会注意到
与方法2相同,但使用AJAX
答案 2 :(得分:1)
另一种方法是使用以下内容启动页面:
<div id="displayarea">
display something here
</div>
<cfflush>
然后做你需要做的任何处理。一旦完成,就做这样的事情。
<cfsavecontent variable = "newdisplay_cf>
generate html here
</cfsavecontent>
<script>
<cfoutput>
var #toScript(newdisplay_cf, "newdisplay_js")#
</cfoutput>
document.getElementById("displayarea").value = newdisplay_js;
</script>
这里可能存在一些语法错误。我只是将代码输入textarea。
答案 3 :(得分:1)
几年前我有一个遗留系统有类似的问题。
在表格上,我做了两件事:
我启动CFTHREAD
来处理处理。
我更新了一个数据库字段,让应用程序知道该作业正在处理。
这样,无论何时查看页面,该数据库字段(或应用程序变量,无论你喜欢它)都被设置为true
我知道要显示一条消息,“请稍后再回来查看,您的请求正在处理中。“
当CFTHREAD
完成后,我会将数据库字段更新为false
,页面将返回正常状态。回想起来,应用程序变量本来是一个更好的解决方案。如果CF崩溃或重新启动,您的数据库不会错误地报告正在运行的进程。
答案 4 :(得分:1)
对于任何希望延长超时时间的人来说,Ben Nadel有一篇关于&#39; cfsetting requestTimeOut&#39;
的好帖子http://www.bennadel.com/blog/626-CFSetting-RequestTimeout-Updates-Timeouts-It-Does-Not-Set-Them.htm
这并没有解决通知问题,但是一旦完成就会呈现页面,所以它解决了我的问题
设置多个超时级别的示例代码
<!--- Set the current time out to be 3 seconds. --->
<cfsetting requesttimeout="3" />
<!---
Get the millisecond start time for page processing
(so that later on, we can check to see how long
the page ran overall).
--->
<cfset intStart = GetTickCount() />
<!--- Try to kill some time. --->
<cftry>
<!---
Here, we are killing time - 4 seconds to be
approximate. This will exceed the request time
out set above (3 seconds) and will throw an error.
--->
<cfset KillTime( 4000 ) />
<!--- The KillTime() method call has timed out. --->
<cfcatch>
First Timeout!<br />
<!---
In an attempt to "recover" from this time out,
update the request time out to be six seconds.
--->
<cfsetting requesttimeout="6" />
<!--- Try to kill some more time. --->
<cftry>
<!---
We are going to try and kill about four
seconds. If this is in terms of the six-second
timeout set above, this should NOT timeout.
However, if this is in the context of the
overall page time (including previous kill time
calls), then this will timeout.
--->
<cfset KillTime( 4000 ) />
<!--- The KillTime() method has timed out. --->
<cfcatch>
Second Timeout!<br />
</cfcatch>
</cftry>
</cfcatch>
</cftry>