问题
Mathematica has the CheckAbort
function which allows to catch and handle user-generated and programmatic Abort
s. But it does not allow to catch interrupts generated by such functions as TimeConstrained
and MemoryConstrained
:
TimeConstrained[CheckAbort[Pause[100], Print["From CheckAbort"]], 1]
(does not print "From CheckAbort"
).
Is there a way to catch such interrupts in Mathematica?
EDIT: I do know that third argument of TimeConstrained
and MemoryConstrained
allows to evaluate some code in the case of interrupt but this way is not what I need: I need a way to handle such interrupts entirely inside of my function allowing a user do not care of its internals.
P.S. The reason why I need this is that I have a function that creates MathLink
objects which must be closed in the case of any interrupts or aborts but not in other cases.
回答1:
The construct for this is available in undocumented form.
Internal`WithLocalSettings[
preprocessing,
code,
postprocessing]
will cause postprocessing to take place before returning from aborts or various types of jumps.
See also:
Reliable clean-up in Mathematica
Import big files/arrays with mathematica
Daniel Lichtblau
回答2:
Here is improved version of WReach's solution (he suggested it in a comment to the answer by Daniel Lichtblau). I should redefine my function f
as follows (and now call it as ff
):
ClearAll[ff];
SetAttributes[ff, HoldAllComplete];
ff[expr_] /; (Unset[done]; True) :=
Internal`WithLocalSettings[Null, done = f[expr],
AbortProtect[If[! ValueQ[done], Print["Interrupt!"]]; Unset[done]]]
Examples:
ff[1 + 1]
(*=>f[2]*)
TimeConstrained[ff[Pause[10]; 1 + 1], 1]
(*=> prints "Interrupt!"*)
TimeConstrained[ff[Pause[.10]; 1 + 1], 1]
(*=>f[2]*)
回答3:
TimeConstrained[Pause[100], 1, Print["-->Aborted"]]
and
MemoryConstrained[100!, 1, Print["-->Aborted"]]
来源:https://stackoverflow.com/questions/7586735/how-to-catch-interrupts-generated-by-timeconstrained