How to catch interrupts generated by TimeConstrain

2019-03-20 19:53发布

问题:

Mathematica has the CheckAbort function which allows to catch and handle user-generated and programmatic Aborts. 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"]]