2011-10-02 50 views
5

此示例例程在內核窗口中生成兩個Throw :: nocatch警告消息。他們可以以某種方式處理嗎?由JLink或UseFrontEnd生成的未捕獲的投擲

該示例包含這些代碼用C創建的文件 「test.m」 的:\ TEMP:

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" 

enter image description here

補遺

使用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:

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

此代碼:使用包含單個細胞產生的\ Temp \ run.nb從Windows命令提示符啓動,將以交互方式運行並保存其輸出。這是不可能實現使用UsingFrontEnd或MathKernel -script「C:\ Temp \ test.m」。

+0

@ Leonid,它也可以在內核窗口中正常工作。這個問題似乎是-initfile方法和JLink之間的一些交互。沒有使用-script的消息,但這不符合我的要求。目前在M8.0.1 XP SP3上。明天會嘗試不同的機器。 –

+0

對不起 - 我只是錯過了那些錯誤。我現在重現他們。不知道爲什麼之前沒有注意到他們。 –

回答

5

在初始化期間,內核代碼處於防止終止的模式。

拋出/捕獲使用Abort實現,因此它們在初始化期間不工作。

一個簡單的例子,顯示問題是把這個在您的test.m文件:

Catch[Throw[test]]; 

同樣,像TimeConstrained,MemoryConstrained,休息,跟蹤家庭,中止和那些函數依賴於它(如某些數據小程序)在初始化過程中會出現類似的問題。

一個可能的解決方案,您的問題可能是考慮-script選項:

math.exe -script test.m 

而且,請注意,在8版本有文件函數調用UsingFrontEnd,它做什麼UseFrontEnd做到了,但汽車配置,所以這個:

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

應該是你的test.m文件中的所有需要​​。

參見:Mathematica Scripts

附錄

一個可能的解決方案使用-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]; 
[email protected]@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 ] ] 

但這踢內核終端會話到一個模式對話框,這似乎是一個bug 給我(我會檢查這個並得到這個報告,如果這是一個有效的問題)。

+0

@阿諾德,感謝您的解釋。我正在使用UseFrontEnd來啓動一個交互式前端來捕獲輸出,正如我剛剛添加的附錄所展示的。無論是UsingFrontEnd還是MathKernel -script都不利於此,所以我打算繼續使用UseFrontEnd,儘管使用nocatch警告消息。 –

+0

@ Arnoud,'NotebookEvaluatingQ'方法很有趣。 –