开发者

How to catch interrupts generated by TimeConstrained?

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 Mathe开发者_如何学Cmatica?

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.


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


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]*)


TimeConstrained[Pause[100], 1, Print["-->Aborted"]]

and

MemoryConstrained[100!, 1, Print["-->Aborted"]]


I am putting this here just to flesh out Danny's answer. I think this is clearly a bug in CheckAbort, and would use this as a workaround:

Attributes[myCheckAbort] = {HoldAll};
myCheckAbort[arg1_, arg2_] := Block[
    {res, aborted},
    WithCleanup[
        aborted = True
        ,
        res = arg1;
        aborted = False;
        res
        ,
        If[aborted,
            arg2;
            res = $Aborted
        ]
    ]
]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜