2016-01-07 2 views
0

Я использую Qt5 на платформе Windows7.
У меня есть приложение, работающее 24/24, что он должен подключиться к некоторым удаленным устройствам, чтобы открыть или закрыть службу на них. Соединение осуществляется через TCP.
Для каждого дня недели есть/должна быть возможность установить час & минуту для обеих операций/задачи: открытой службы и крупный сервис, как в коде ниже:Qt5: Как выполнить «задачу» на основе недельного планировщика?

#define SUNDAY  0 
#define MONDAY  1 
//... 
#define SATURDAY 6 

struct Day_OpenCloseService 
{ 
    bool automaticOpenService; 
    int openHour; 
    int openMinute; 
    bool automaticCloseService; 
    int closeHour; 
    int closeMinute; 
}; 
QVector<Day_OpenCloseService> Week_OpenCloseService(7); 

Week_OpenCloseService[SUNDAY].automaticOpenService = true; 
Week_OpenCloseService[SUNDAY].openHour = 7; 
Week_OpenCloseService[SUNDAY].openMinute = 0; 
Week_OpenCloseService[SUNDAY].automaticCloseService = false; 
// 
Week_OpenCloseService[MONDAY].automaticOpenService = true; 
Week_OpenCloseService[MONDAY].openHour = 4; 
Week_OpenCloseService[MONDAY].openMinute = 30; 
Week_OpenCloseService[MONDAY].automaticCloseService = true; 
Week_OpenCloseService[MONDAY].closeHour = 23; 
Week_OpenCloseService[MONDAY].closeMinute = 0; 
// ... 
Week_OpenCloseService[SATURDAY].automaticOpenService = true; 
Week_OpenCloseService[SATURDAY].openHour = 6; 
Week_OpenCloseService[SATURDAY].openMinute = 15; 
Week_OpenCloseService[SATURDAY].automaticCloseService = false; 
Week_OpenCloseService[SATURDAY].closeHour = 23; 
Week_OpenCloseService[SATURDAY].closeMinute = 59; 

If automaticOpenService true в течение дня, то открытый сервис будет выполнен в указанный час & минута, в новом потоке (я полагаю).
Если automaticOpenService является ложным, то для этого дня недели открытое обслуживание не выполняется.
И то же самое относится и к automaticCloseService ...

Теперь вопрос:
Как начать открытой службы и крупным обслуживание задач, на основе выше «планировщик»?

Хорошо, задачи открытого и закрытого обслуживания еще не реализованы, но они будут лишь некоторыми простыми командами через TCP-соединение с удаленными устройствами (которые прослушивают определенный порт).
Я все еще взвешиваю, как реализовать это тоже ... (однопоточный, многопоточный, параллельный и т. Д.).

ответ

1

Основная реализация планировщика будет содержать список предстоящих задач (возможно, только с двумя элементами в списке в вашем случае), которые сортируются по времени, когда эти задачи должны быть выполнены. Поскольку вы используете Qt, вы можете использовать объекты QDateTime для представления времени, в которое должны быть выполнены ваши предстоящие задачи.

Как только у вас установлен этот список, просто нужно вычислить, сколько секунд осталось между текущим временем и меткой времени первого элемента в списке, а затем ждать этого количества секунд. Метод QDateTime::secsTo() очень полезен здесь, поскольку он будет делать именно этот расчет для вас. Затем вы можете позвонить QTimer::singleShot(), чтобы сделать так, чтобы в течение многих секунд выходил сигнал.

Когда выдается сигнал qTimer и вызывается ваш метод slot, метод slot проверяет QDateTime первого элемента в списке; если текущее время больше или равно QDateTime этого элемента, то пришло время выполнить задачу, а поп этот элемент с головы списка (и, возможно, перенести новую задачу на завтра?). Повторяйте до тех пор, пока список не будет пуст, или первый элемент в списке имеет QDateTime, которое все еще находится в будущем, и в этом случае вы снова вернетесь к шагу 1. Повторите бесконечно.

Обратите внимание, что для выполнения этой задачи в Qt не требуется многопоточность (и использование многопоточности не облегчит задачу), поэтому я мог бы избежать ее, если это возможно).

+0

Я думал точно так же, как вы предлагаете выше, но я боюсь, что здесь есть проблема: предположим, что пользователь (GUI предоставит, что в окончательной версии приложения) решает изменить автоматическое открытие/закрытие часов. .. Тогда что происходит со всеми таймерами singleShot(), которые все еще активны? Существуют ли какие-либо способы убить/удалить запущенный таймер? Вы видите, моя забота здесь в том, что все механизмы планировщика могут быть испорчены таймерами ...Я уверен, что вы понимаете, что я имею в виду :) –

+0

О вашей заметке о многопоточности: что я имел в виду, так это то, что для удобства реагирования пользовательского интерфейса (GUI), было бы разумно бросить открытый/закрыть задачу (TCP-подключения к удаленным устройствам) в новом/отдельном потоке ... Я прав? –

+0

Для вашей первой проблемы (отмена таймеров) я не знаю, как отменить таймер, но это не обязательно, потому что ваш подключенный слот-метод должен иметь возможность обрабатывать ранние или поздние пробуждения изящно , В частности, когда он вызывается, он должен проверять текущее системное время и выполнять только те задачи, которые были запланированы на или до текущего времени, а затем пересчитывать время до следующего события и устанавливать для него новый таймер. Таким образом, он всегда будет работать, даже если он получит сигнал «слишком рано», он просто ничего не сделает и вернется к ожиданию. –