1

我有一些冗长而复杂的代码,需要进行一些解析,并且需要一段时间才能完成,在这种情况下优化代码没有多大意义。

处理长执行时间并让用户知道何时完成的策略是什么?


解释为什么优化没有多大意义

该应用程序具有面向最终用户的页面和非面向最终用户的页面。在非用户区域,我正在解析几个 excel 电子表格。加载和循环这些需要很长时间。我优化了代码以在我的超时限制内运行,它今天可能工作,但一个月后我可能会导入一个 4 倍长的文件,它不会再次工作。我要解决的问题是绕过我知道需要很长时间的特定操作的 cf 超时。

我尝试过使用线程,但由于某种原因在 CF9 上工作但在 CF8 上没有工作(尽管它们受支持)

我也刚刚发现cfsetting requestTimeOut哪些可以做我需要做的事情。

4

5 回答 5

3

几年前我有一个遗留系统也有类似的问题。

在表单发布时,我做了两件事:

  1. 我开始CFTHREAD处理处理。

  2. 我更新了一个数据库字段,让应用程序知道该作业正在处理中。

这样,无论何时查看页面,并且该数据库字段(或应用程序变量,无论您喜欢它)都设置为true我知道会显示一条消息,例如“请稍后再回来查看,您的请求正在处理中。”

完成CFTHREAD后,我会将 DB 字段更新为false,然后页面将恢复正常状态。回想起来,应用程序变量会是一个更好的解决方案。如果 CF 崩溃或重新启动,您的数据库不会错误地报告正在运行的进程。

于 2012-12-10T14:58:40.907 回答
2

您可能已经对其进行了研究,但请查看是否可以缓存任何内容,以减少等待的时间。

至于将其传达给用户,首先要确保用户知道事情何时发生。程序可以做的最糟糕的事情之一就是接收输入而不做出反应。确保用户在发生某些事情时很清楚。显示加载的方式取决于您。如果加载时间低于大约十秒左右,则可能会有沙漏,但如果等待时间较长,您可能需要进度条或类似的东西。

如果有任何方法可以允许其中一些在后台或其他进程中发生,这可能有助于减轻负载。否则,弹出一个建议,告诉他们去喝咖啡。:)

这只是一个只有一点信息的下意识的回应,但如果你能对你正在寻找的东西和粗略的加载时间估计提供更多的想法,我可能会得到更具体的信息。

于 2012-12-07T19:22:30.867 回答
1

方法一

我在 II6 和 CF 7 上有一个站点。我添加了这个通过 Javascript 操作的条形图。然后,我将通过 Javascript 后跟<cfflush>.

在站点升级到 II7.5 和 CF 9 之前它运行良好。由于某种原因<cfflush>不起作用,Javascript 仍然可以设置标准并取得有意义的进展。

方法二

这需要两个 iframe。

  • 一个 iframe 运行长时间运行的进程,并且从用户视图中隐藏。

  • 另一个 iframe 运行一个页面,该页面每 10 秒左右刷新一次。此页面查询慢速进程的后端日志记录。可能会晚 10 秒,但最终用户甚至可能会注意到

方法 3

与方法 2 相同,但使用 AJAX

于 2012-12-07T20:10:47.000 回答
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 中。

于 2012-12-08T17:15:56.033 回答
1

对于其他希望延长超时时间的人,Ben Nadel 有一篇关于“cfsetting requestTimeOut”的好帖子

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>
于 2012-12-13T17:25:53.807 回答