# Checking from a preemptive evaluation whether a main evaluation is ongoing

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.

-

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.

-
+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 9 '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 9 '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

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).

-