5

此示例例程在内核窗口中生成两条 Throw::nocatch 警告消息。可以以某种方式处理它们吗?

该示例包含在 C:\Temp 中创建的文件“test.m”中的此代码:

Needs["JLink`"];
$FrontEndLaunchCommand = "Mathematica.exe";
UseFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];

然后将这些命令粘贴并在 Windows 命令提示符处运行:

PATH = C:\Program Files\Wolfram Research\Mathematica\8.0\;%PATH%
start MathKernel -noprompt -initfile "C:\Temp\test.m"

在此处输入图像描述

附录

使用 UseFrontEnd 而不是 UsingFrontEnd 的原因是,可能需要交互式前端来保存通常以交互方式运行的笔记本的输出和消息。例如,使用 C:\Temp\test.m 修改如下:

Needs["JLink`"];
$FrontEndLaunchCommand="Mathematica.exe";
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
SelectionMove[nb, Next, Cell];
SelectionEvaluate[nb];
];
Pause[10];
CloseFrontEnd[];

和一个笔记本 C:\Temp\run.nb 使用包含以下内容的单个单元格创建:

x1 = 0; While[x1 < 1000000,
 If[Mod[x1, 100000] == 0,
  Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]];

此代码从 Windows 命令提示符启动,将以交互方式运行并保存其输出。这是无法使用 UsingFrontEnd 或 MathKernel -script "C:\Temp\test.m" 来实现的。

4

1 回答 1

5

在初始化期间,内核代码处于防止中止的模式。

Throw/Catch 是通过 Abort 实现的,因此它们在初始化期间不起作用。

显示问题的一个简单示例是将其放入您的 test.m 文件中:

Catch[Throw[test]];

类似地,TimeConstrained、MemoryConstrained、Break、Trace 系列、Abort 等函数以及依赖于它的函数(如某些数据包)在初始化期间也会出现类似问题。

您的问题的可能解决方案可能是考虑 -script 选项:

math.exe -script test.m

另外,请注意,在版本 8 中,有一个名为 UsingFrontEnd 的文档化函数,它执行 UseFrontEnd 所做的工作,但它是自动配置的,因此:

Needs["JLink`"];
UsingFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];

应该是你在 test.m 文件中所需要的。

另请参阅:Mathematica 脚本

附录

使用 -script 和 UsingFrontEnd 的一种可能解决方案是使用下面包含的 'run.m 脚本。这确实需要在内核配置选项中设置一个“测试”内核(基本上是“本地”内核设置的克隆)。

该脚本包括两个实用函数,NotebookEvaluatingQ 和 NotebookPauseForEvaluation,它们帮助脚本在保存之前等待客户端笔记本完成评估。这种方法的好处是所有评估控制代码都在'run.m'脚本中,因此客户端笔记本不需要在末尾有 NotebookSave[EvaluationNotebook[]] 语句。

NotebookPauseForEvaluation[nb_] := Module[{},While[NotebookEvaluatingQ[nb],Pause[.25]]]

NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or@@Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]

UsingFrontEnd[
nb = NotebookOpen["c:\\users\\arnoudb\\run.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb];
]

我希望这在某种程度上对你有用。它可以使用更多改进,例如将笔记本的内核重置为其原始内核并在保存后关闭笔记本,但此代码应适用于此特定目的。

在旁注中,我尝试了另一种方法,使用这个:

UsingFrontEnd[ NotebookEvaluate[ "c:\\users\\arnoudb\\run.nb", InsertResults->True ] ]

但这会将内核终端会话踢入对话模式,这对我来说似乎是一个错误(如果这是一个有效的问题,我会检查并报告此问题)。

于 2011-11-08T17:05:54.763 回答