Программирование длительного процесса, основанного на времени - PullRequest
1 голос
/ 26 июля 2010

Мне было интересно, как лучше написать приложение. По сути, у меня есть проект спортивного симулятора, который является многопоточным и может одновременно выполнять различные симуляции игры.

Я храню свои совпадения в базе данных SQLite, к которой прикреплен DateTime.

Я хочу написать приложение, которое проверяет каждый час или около того, чтобы увидеть, нужно ли играть какие-либо новые матчи и порождает эти темы.

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

Я написал свою объектную модель так, чтобы каждый объект загружался из памяти только один раз, поэтому, пока все потоки моделирования порождаются из этого одного приложения, они не должны перезаписывать данные.

РЕДАКТИРОВАТЬ: Подробнее о требованиях

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

Я предполагаю, что это программа, которая работает в фоновом режиме (сервис, я полагаю?), Который спит в течение 60 минут, а затем проверяет базу данных, чтобы увидеть, следует ли запускать какие-либо игры. Если есть что-то, что нужно запустить, он запускает потоки для имитации этих игр, а затем возвращается в режим сна. Следовательно, потоки моделирования работают, но поток «планирования» спит еще 60 минут.

Причина, по которой я не могу (я думаю) использовать интерфейс планирования задач ОС по умолчанию, заключается в том, что для этого требуется, чтобы задача, которую нужно выполнить, была отвергнута как новый процесс. Я разработал мою объектную модель базы данных так, чтобы они кэшировались каждым классом объектов при первой загрузке (ссылка на память), что означает, что каждый объект загружается из памяти только один раз, и эта ссылка используется во всех сохранениях. Это означает, что когда каждый поток моделирования завершается и сохраняет свое состояние, для сохранения состояния используется одна и та же ссылка (с обновленным состоянием). Если каждый раз запускается другой исполняемый файл, предположительно, каждый процесс открывает разные ссылки на память, и, следовательно, один процесс может сохранить в БД и перезаписать состояние, записанное другим процессом.

Служба выглядит как путь. Есть ли способ заставить службу просто спать 60 минут, а потом проснуться и выполнить функцию? Я чувствую, что создание этого стандартного консольного приложения приведет к потере памяти, но я не знаю, есть ли эффективный способ сделать это, о котором я не знаю.

Ответы [ 2 ]

2 голосов
/ 26 июля 2010

Если вы хотите сделать его действительно надежным, сделайте его Сервисом.

Но я не вижу проблем в том, чтобы сделать его обычным (Console, WinForms, WPF) приложением.* Может быть, вы могли бы немного расширить требования.

0 голосов
/ 27 июля 2010

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

Если вы хотите, чтобы все оставалось в кэше навсегда, тогда вам нужно иметь приложение, которое просто работает вечно.Вы можете сделать это службой Windows или обычным приложением Windows.
Служба Windows - это просто обычный exe-файл, соответствующий API-интерфейсу диспетчера служб.Если вы хотите создать его, в Visual Studio есть мастер, который автоматически генерирует для вас скелетный код.По сути, вместо метода Main у вас есть класс Service с методом Run, а все остальное - то же самое.

Вы можете, если хотите, использовать планировщик задач Windows для планированияваши действия.Чтобы сделать это, нужно, чтобы фоновая служба Windows работала в фоновом режиме и ничего не делала.Пусть он откроет сокет TCP или именованный канал или что-то еще и просто сидит там.Затем напишите небольшой исполняемый файл-заглушку, который просто подключается к этому сокету или именованному каналу и говорит фоновому приложению проснуться.
Это, конечно, намного сложнее, чем просто выполнить sleep в фоновом приложении,но он дает вам гораздо больше контроля - вы можете изменить время ожидания, не перезапуская фоновый сервис, запускать его по требованию и т. д.


Я бы, однако, рассмотрел ваш дизайн.Тот факт, что вы полагаетесь на долгосрочную службу, является большой точкой отказа.Если ваше приложение должно работать в течение нескольких дней, и у вас есть одна ошибка, которая приводит к его падению, тогда вам нужно начать заново.Гораздо лучшая архитектура состоит в том, чтобы следовать модели Unix, где у вас есть небольшие процессы, которые запускаются, делают одно, а затем заканчивают (в этом случае обрабатывайте каждую игровую симуляцию как свой собственный процесс, поэтому, если кто-то умирает, он не берет основной процессили другие симуляции не работают).

Похоже, что основная причина, по которой вы пытаетесь обеспечить его длительную работу, заключается в кэшировании запросов к базе данных.Тебе вообще нужно это делать?Много времени базы данных достаточно быстрые (у них есть свои собственные кеши, которые достаточно умны).Распространенная ошибка, которую я видел программистов, заключается в том, чтобы просто предполагать, что что-то вроде базы данных работает медленно, и тратить кучу времени на оптимизацию, когда на самом деле все будет хорошо

...