Как запрашивать состояние (активно или нет) запланированной задачи? - PullRequest
5 голосов
/ 29 октября 2011

Какой предпочтительный способ проверить, является ли запланированное задание активным или нет?

Ниже я опишу свое решение, но я не уверен, что это действительно лучший способ сделать это.


Запланированное задание создается следующим образом:

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

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

Мы можем проверить существующие задачи следующим образом:

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

Последняя запись в ScheduledTaskObject (True или False) отображается, чтобы указать, запущена задача или нет.

Теперь давайте запустим задачу и сравним содержимое переменной myTask со списком, возвращаемым 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]}

Обратите внимание, что они отличаются. Переменная показывает False, а ScheduledTasks[] показывает false. Это показывает, что переменная фактически не содержит объект задачи. Изменяя переменную myTask напрямую, мы не можем изменить задачу. Реальное состояние задачи возвращается ScheduledTasks[].

Кажется разумным предположить, что первая запись в выражении ScheduledTaskObject является уникальным числом, соответствующим задаче. Таким образом, любая ручная операция, выполняемая над задачей, может использовать этот номер как «дескриптор», и мы можем проверить состояние задачи с идентификатором 1, например:

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

Я совсем не уверен, что этот подход (с использованием идентификатора из ScheduledTaskObject) является правильным. Я заметил ситуации, когда в новом ядре уже были некоторые задачи (возможно, из-за внешнего интерфейса - у меня было несколько открытых ноутбуков, некоторые с динамическими элементами, и я экспериментировал с задачами), а иногда ScheduledTasks[] возвращает несколько задач с одинаковым идентификатором (обычно 0).

В итоге:

  1. Это надежный способ обработки задач по их идентификатору (первое число из их ScheduledTaskObject)?

  2. Как правильно запрашивать состояние запланированной задачи, учитывая выражение, которое мы получаем из CreateScheduledTask при первом создании?

РЕДАКТИРОВАТЬ: Если это возможно, было бы также неплохо иметь динамическую ячейку, отображающую состояние запланированной задачи, без использования слишком большого количества ЦП. У кого-нибудь есть идеи как это сделать?

1 Ответ

5 голосов
/ 29 октября 2011

Документация для ScheduledTaskObject действительно использует id для первого аргумента, и я думаю, что действительно уникален.Я не смог воспроизвести несколько ScheduledTaskObjects с тем же идентификатором, который вы указали (ни один с 0), поэтому, если бы вы могли предоставить минимальный пример, было бы неплохо.

В любом случае (при условииболее чем одна задача имеет один и тот же идентификатор), вы можете сузить соответствие, также проверив точное определение задачи.Вот ваша простая модификация.

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

Вы можете создать Dynamic вывод состояния вашей задачи и установить интервал обновления, равный примерно 1 секунде (или более), чтобы он неt постоянно опрашивает государство, следовательно, замедляет вас.

Dynamic[Refresh[pollState[myTask], UpdateInterval -> 1]]
...