# TimeConstrained dynamic change of maximum time

I would like to run a time consuming function:

TimeConstrained[f[x],maxseconds]


and be able to change maxseconds during running (increasing or decreasing max time) using a slider. Ideally when i decrease maxseconds below the time it has already consume it will stop.

I could implement such a functionality inside f but i would have to do this for all f i want to create , so this way is out of the question.

Theodore.

-
This is a tough one. Basically it boils down to the fact that once a long calculation is started, you cannot interrupt it programmatically from the outside (i.e. not from the inside as in case of e.g. EventMonitor:>If[aborted, Abort[]]) with any Abort[], even using a background scheduled task to monitor elapsed time. –  István Zachar Nov 29 '13 at 12:47
I understand your point. This is why I opened the bounty - in case there is a way of generalizing TimeConstrained maybe with some low level Java programming? –  tchronis Nov 29 '13 at 14:24
Perhaps "EvaluatorAbort" could be used. –  Michael E2 Nov 29 '13 at 15:44
Thanks @MichaelE2 for the input! –  István Zachar Nov 29 '13 at 18:25
Another completely different approach would be to abuse one of the parallel kernels to run the computation in a detached thread. After all, the parallel kernels are just simple kernels you can use for calculation. In this way you could work in the front end while your f[x] is calculated in the background and you can stop the calculation at any time. –  halirutan Nov 30 '13 at 2:55

Thanks to Michael E2's comment, the following approach is successful. The method sets up a scheduled task that (at certain resolution res) monitors the elapsed $time and compares it to the dynamic $max. If $time is more than allowed by $max, it calls the front-end "EvaluatorAbort".

Attributes[dynamicTimeConstrained] = {HoldAll};
dynamicTimeConstrained[expr_] := Module[{task, res = .1},
$time = 0; task = RunScheduledTask[($time = $time + res; If[$time >= $max, RemoveScheduledTask@task; FrontEndExecute@FrontEndCellPrint@Cell[ "Aborted at "<>ToString@$time<>".", "Output"];
FrontEndExecute@FrontEndToken@"EvaluatorAbort"
];
), {res, Infinity}];
res = expr;
res
];

$time = 0;$max = 3;
Dynamic@$time (* set up slider to dynamically manipulate$max *)
Slider[Dynamic@$max, {0.0001, 10}, Appearance -> "Labeled"] (* simulate a long calculation by Pause *) dynamicTimeConstrained[Do[Pause@1; Print[i];, {i, 5}]; 111]  Notice that the scheduled task is aware of the global value changes to both $time and \$max`, so the method works. May need a bit of fine tuning on the correct time-resolution as too fine a resolution might cause delayed abortion.

Here the default allotted time (3 sec) is extended, so the calculation terminates normally without abort:

Here the default time (3 sec again) is decreased and the job aborts as expected:

-
Great job! Glad the comment helped. :) –  Michael E2 Nov 29 '13 at 18:31
@tchronis Thanks for the accept and the bounty! I hope this method can be used in realistic situations as well. –  István Zachar Dec 13 '13 at 7:56