5

What is the preferred way to check whether a scheduled task is active or not?

I'll outline my solution below, but I am not sure this is indeed the best way to do it.


A scheduled task is created like this:

In[1]:= myTask=CreateScheduledTask[Print["task 1"], 30]

Out[1]= ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]

We can check for the existing tasks like this:

In[2]:= ScheduledTasks[]
Out[2]= {ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]}

The last entry in the ScheduledTaskObject (True or False) appears to indicate whether the task is started or not.

Now let's start the task, and compare the contents of the variable myTask with the list returned by ScheduledTasks[].

In[3]:= StartScheduledTask[myTask]
Out[3]= ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]

In[4]:= {ScheduledTasks[],myTask}
Out[4]= {{ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,True]},
          ScheduledTaskObject[1,Print[task 1],{30,Infinity},Automatic,False]}

Note that they differ. The variable shows False while ScheduledTasks[] shows false. This demonstrates that the variable does not actually hold the task object. By modifying the variable myTask directly we can't modify the task. The real state of the task is returned by ScheduledTasks[].

It looks reasonable to assume though that the first entry in the ScheduledTaskObject expression is a unique number corresponding to the task. So any manual operation performed on the task could perhaps use this number as a "handle", and we could check the state of task with identifier 1 like this:

Cases[ScheduledTasks[], ScheduledTaskObject[1,__,state_] :> state]

I am not sure at all though that this approach (using the identifier from the ScheduledTaskObject) is correct. I have noticed situations when there were already some tasks in a fresh kernel (probably due to the front end --- I had several notebook open, some with dynamic elements, and I've been experimenting with tasks), and sometimes ScheduledTasks[] returns several tasks with the same identifier (usually 0).

In summary:

  1. Is it a reliable way to handle tasks by their identifier (the first number from their ScheduledTaskObject)?

  2. What is the correct way to query the state of a scheduled task, given the expression we get from CreateScheduledTask when we first create it?

EDIT: If it's possible, it would also be nice to have a Dynamic cell showing the state of a scheduled task, without using too much CPU. Does anyone have any ideas about how to do this?

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
Szabolcs
  • 24,728
  • 9
  • 85
  • 174

1 Answers1

5

The documentation for ScheduledTaskObject indeed uses id for the first argument and I think it is indeed unique. I have not been able to reproduce multiple ScheduledTaskObjects with the same id as you claim (nor ones with 0), so if you could provide a minimal example, it would be nice.

In any case (assuming more than one task has the same id), you can narrow down your match by also checking for the exact definition of the task. Here's a simple modification of yours.

 Clear@pollState
 pollState[task_ScheduledTaskObject] := 
 Module[{id = Level[task, 1][[1]], expr = Level[task, 1][[2]]},
  out = Cases[ScheduledTasks[], 
    ScheduledTaskObject[Evaluate@id, Evaluate@expr, __, state_] :> 
     state];
  Return[If[out === {}, "Task not found", First@out]]]

You can create a Dynamic output of the state of your task and set the update interval to something like 1 second (or more), so that it doesn't constantly poll for the state, hence slowing you down.

Dynamic[Refresh[pollState[myTask], UpdateInterval -> 1]]
abcd
  • 41,765
  • 7
  • 81
  • 98
  • I'll try to come up with a minimal example, though it's not easy because I believe it was due some front end interaction. Occasionally evaluating `ScheduledTasks[]` right after `Quit` gave two tasks, both with id `0`. – Szabolcs Oct 29 '11 at 14:51
  • @Szabolcs I wouldn't be surprised if the id 0 was assigned specifically for kernel related tasks. User defined tasks all start from 1. It might be easy to just include a check to exclude 0 (which won't be necessary, as `myTask` will have `id>0`) – abcd Oct 29 '11 at 15:01
  • Start Mathematica, and evaluate something. Then evaluate `Quit`. Then evaluate `ScheduledTasks[]`. I get a list of three elements, all with ID 0: http://pastie.org/2778819 – Szabolcs Oct 29 '11 at 16:23
  • @Szabolcs Thanks, I can reproduce it now. However, those look like the kernel initialization tasks and should disappear after the first evaluation. Indeed if you do evaluate something and then try `ScheduledTasks[]`, you'll get `{}`. I'm not convinced that this is be a problem. Even if you do encounter them later, you can safely ignore `0` id tasks, as yours will definitely be `id>0`. – abcd Oct 29 '11 at 19:22