9

How can I programmatically check from a preemptive evaluation whether a main evaluation is currently ongoing?

I need a function mainEvaluationOngoingQ[] so that

Button["Evaluating?", Print@mainEvaluationOngoingQ[], Method -> "Preemptive"]

will print True only if a main evaluation is ongoing.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263

2 Answers2

14

If you control the launch of the main evaluation process, then a very simple way is to wrap your code in a dynamic environment (Block), which would set some flag:

mainEvaluationOngoingQ[] := TrueQ@mainEvaluationQ

Block[{mainEvaluationQ = True}, Do[i^2, {i, 1, 10^8}]]

You can automate this by creating an environment:

SetAttributes[withMainEvaluation, HoldAll];
withMainEvaluation[code_] :=
    Block[{mainEvaluationQ = True}, code]

You can further automate this with $Pre, if needed: $Pre = withMainEvaluation.

F'x
  • 10,817
  • 3
  • 52
  • 92
Leonid Shifrin
  • 114,335
  • 15
  • 329
  • 420
  • +1 Very nice. I hope his main evaluations aren't triggered by buttons with Method->"Queued". Any way to cover those cases too? – Rojo Feb 09 '12 at 17:58
  • @Rojo If buttons are generated in the same session, then I'd write a preprocessor that would dynamically generate code where the body of the button is wrapped in withMainEvaluation. If not, one can probably write code which would pre-process a notebook and change that at the box level. Other than that, I don't know how to do this - this may need some lower-level stuff. – Leonid Shifrin Feb 09 '12 at 18:11
  • I'm very late with this, but isn't that question superfluous: With Method->"Queued", the evaluation is queued to be evaluated using the main link, so there by definition isn't a (-nother) main evaluation running, and mainEvaluationOngoing always returns False, which is correct when interpreted as "is another main evaluation ongoing". Or am I missing something? – Albert Retey May 22 '13 at 14:05
  • @AlbertRetey Yes, but IIRC, the question was about how to determine whether or not the main evaluation is ongoing, from the preemptive evaluation, not from the queued one. – Leonid Shifrin May 22 '13 at 14:23
3

The following works with Mathematica 8.0.0.0:

Button["Evaluating?",Print@(Drop[Stack[],-7]!={}),Method->"Preemptive"]

However the -7 here is an empirical factor which removes all those entries generated from executing the button code itself; it changes depending on the exact form of the code the Stack[] is embedded in, and might even depend on the Mathematica version (I don't think the inner mechanics of Button is documented, let alone guaranteed never to change).

celtschk
  • 19,133
  • 1
  • 51
  • 106