为啥会话崩溃后 Progress 会返回初始屏幕?

Posted

技术标签:

【中文标题】为啥会话崩溃后 Progress 会返回初始屏幕?【英文标题】:Why does Progress go back to the initial screen after a session crash?为什么会话崩溃后 Progress 会返回初始屏幕? 【发布时间】:2021-12-14 03:07:00 【问题描述】:

大家好,感谢您查看此问题,

我有一个用户可以通过登录屏幕访问的程序。一旦在登录屏幕上验证了用户的凭据,就会调用主程序(从登录屏幕)并且登录屏幕消失。都好。但是,如果会话崩溃(或者我按下 CTRL-PAUSE),主程序就会终止,我最终会进入初始登录屏幕。我假设在会话崩溃后,Progress (11.4) 应该带我回到操作系统 (Windows Server 2012),而不是回到初始屏幕。我尝试将 QUIT 放置在程序的不同区域,但 Progress 仍然让我回到初始屏幕,而我需要它完全退出。任何想法将不胜感激。谢谢!

【问题讨论】:

【参考方案1】:

在发生未处理的 STOP 条件后重新运行启动过程是 AVM 的默认行为。

你可以添加一个

ON STOP UNDO, RETURN "stopped" . 

在“崩溃”发生的地方关闭 DO、FOR 或 REPEAT 块的选项。然后调用过程可以检查“停止”的返回值。

假设您使用的是最新版本 (OpenEdge 12.x),您还可以将 CATCH 块用于 Progress.Lang.Stop:

CATCH stopcon AS Progress.Lang.Stop:
    QUIT.
END CATCH.

【讨论】:

感谢您的及时回复,迈克!会话崩溃可能发生在许多不同的程序中(由于外部接口)。是否有任何方法可以确定登录屏幕是从新会话开始还是从崩溃的会话开始(除了使用标志)?非常感谢。【参考方案2】:

我认为您对“崩溃”一词的使用非常非常令人困惑。如果您的会话实际上在 _progres(或 prowin,如果这是 Windows)终止的通常意义上“崩溃”,那么您将不会保留任何锁定的记录。您还会有一个 protrace 文件,可以帮助您确定问题发生的位置。

顺便说一句,您可以在客户端启动时添加错误日志,以确定 QXten​​d 找不到的错误发生在哪里:

_progres dbname -p startup.p -clientlog logname.log

您没有共享任何代码,所以我只能猜测,但大概您正在通过 -p 启动参数运行您的登录程序。

如果我错了,请纠正我,但有以下几点:

_progres dbname -p startup.p

然后启动程序运行它运行的任何程序,让您登录并运行应用程序。也许是这样的:

/* startup.p
 */

message "(re)starting!".
pause.

run value( "login.p" ).

run value( "stuff.p" ).

message "all done".
pause.

quit.

还有:

/* login.p
 */

message "hello, logging in!". 
pause.

return.

随着:

/* stuff.p  
 */

message "hello, doing stuff!".
pause.

run value( "notthere.p" ).
   
message "hello, doing more stuff!".
pause.

return.

有时会发生错误(您似乎想将此称为“崩溃”)。当 stuff.p 尝试“运行 notthere.p”时,我已安排发生严重错误。因此,如果您运行我的示例,您将看到您所描述的行为 - 您的会话“崩溃”,启动过程重新运行,然后您再次进入登录屏幕。

要改变它并捕获错误,只需在 RUN 语句周围加上“DO ON STOP”。像这样:

/* startup.p
 */

message "(re)starting!".
pause.

do on error undo,  leave
   on endkey undo, leave
   on stop undo,   leave
   on quit undo,   leave:  /* "leave", exits this block when one of the named conditions arises */ 

  run value( "login.p" ).

  run value( "stuff.p" ).

  /* we just leave because we finished normally */

end.

message "all done".
pause.

quit.

您提到了 QXten​​d,所以我猜测 MFG/Pro 参与其中。如果您不能直接修改 MFG/Pro 启动过程(我记得那将是“-p mfg.p”),只需将上面的代码修改为从“DO ON STOP”中运行 mfg.p 的“垫片”。 .." 块。

【讨论】:

感谢您非常全面的解释,汤姆。在我的程序中,我调用 QXten​​d 程序来更新 QAD 中的记录。当处理 QXten​​d 调用的服务器太忙时,它会崩溃,这意味着在那里运行的 Progress 会话停止工作并退出到操作系统。发生这种情况时,我的程序将返回登录屏幕。我会尝试你的建议,我会看看我会怎么做。再次感谢。【参考方案3】:

我相信我已经找到了一种方法,可以使用 ETIME 函数在会话崩溃导致初始登录屏幕出现时退出该屏幕。再次感谢 Mike 的回复。

【讨论】:

你为什么不简单地捕捉和处理错误,然后按照 Mike 的建议退出,如果这是你想做的事情?无论你在 ETIME 上做什么,都会让下一个程序员大开眼界。 嗨,Tom,该错误与 QXten​​d 崩溃有关;负责QXten​​d的程序员一直找不到原因。一旦 QXten​​d 接管,我就无法控制程序。 ETIME 函数允许我退出程序,而不是让崩溃的会话使用锁定的表。感谢您的意见。

以上是关于为啥会话崩溃后 Progress 会返回初始屏幕?的主要内容,如果未能解决你的问题,请参考以下文章

为啥持有 PARTIAL_WAKE_LOCK 会导致随机系统崩溃?

我的启动画面后我的程序不断崩溃。为啥?

可以/为啥在返回类型中使用 char * 而不是 const char * 会导致崩溃?

谷歌浏览器崩溃后恢复会话cookie,如何避免?

为啥重启flink程序后有很多in-progress文件?

HTML 5 Progress 元素冻结在活动中