Pergunta

Gostaria de saber qual seria a melhor forma de escrever uma candidatura.Basicamente, eu tenho um projeto de simulação de esportes que é multi-threaded e pode executar diferentes simulações de jogos simultaneamente.

Eu armazeno minhas correspondências em um banco de dados SQLite que tem um DateTime anexado a ele.

Quero escrever um aplicativo que verifica a cada hora ou mais para ver se novas partidas precisam ser jogadas e gera esses tópicos.

Não posso confiar no Agendador de tarefas para executar isso a cada hora porque há objetos que as diferentes instâncias desse processo compartilhariam (especificamente um objeto de Torneio), Que Suspeito que seriam substituídos por um processo mais recente quando salvos de volta no banco de dados.Então, idealmente, eu preciso escrever algum tipo de processo de longa duração que durma entre horas.

Escrevi meu modelo de objeto para que cada objeto seja carregado apenas uma vez da memória, portanto, desde que todos os threads de simulação sejam gerados a partir deste aplicativo, eles não devem substituir os dados.

Editar:Mais pormenores sobre os requisitos

Basicamente, várias correspondências precisam ser executadas simultaneamente.Essas correspondências podem ser de comprimento arbitrário, portanto, não é necessário que uma termine antes que a outra comece (na verdade, na maioria dos casos, haverá várias correspondências em execução ao mesmo tempo).

O que estou imaginando é um programa que é executado em segundo plano (um serviço, eu acho?) que dorme por 60 minutos e, em seguida, verifica o banco de dados para ver se algum jogo deve ser iniciado.Se houver algum para ser iniciado, ele dispara threads para simular esses jogos e depois volta a dormir.Portanto, os encadeamentos de simulação estão em execução, mas o encadeamento de "agendamento" está adormecido por mais 60 minutos.

A razão pela qual eu não posso (eu acho) usar a interface de agendamento de tarefas padrão do sistema operacional é que eles exigem que a tarefa seja executada para ser rejeitada como um novo processo.Eu desenvolvi meu modelo de objeto de banco de dados de forma que eles sejam armazenados em cache por cada classe de objeto no primeiro carregamento (a referência de memória), o que significa que cada objeto é carregado apenas da memória uma vez e essa referência é usada em todos os salvamentos.O que significa que quando cada thread de simulação é feito e salva seu estado, a mesma referência é usada (com estado atualizado) para salvar o estado.Se um executável diferente for iniciado todas as vezes, presumivelmente uma referência de memória diferente será aberta por cada processo e, portanto, um processo pode salvar no banco de dados e sobrescrever o estado escrito pelo outro processo.

Um serviço parece ser o caminho a percorrer.Existe uma maneira de fazer um serviço apenas dormir por 60 minutos e acordar e executar uma função depois disso?Sinto que tornar este um aplicativo de console padrão desperdiçaria memória, mas não sei se existe uma maneira eficiente de fazer isso da qual não estou ciente.

Foi útil?

Solução

Se você quiser torná-lo realmente confiável, faça um serviço.

Mas não vejo problemas em torná-lo um aplicativo normal (console, winforms, wpf).

Talvez você possa expandir os requisitos um pouco.

Outras dicas

A razão pela qual eu não posso (eu acho) usar a interface de agendamento de tarefas padrão do sistema operacional é que eles exigem que a tarefa seja executada para ser rejeitada como um novo processo.Eu desenvolvi meu modelo de objeto de banco de dados de tal forma que eles são armazenados em cache por cada classe de objeto no primeiro carregamento (a referência de memória), o que significa que cada objeto é carregado apenas da memória uma vez e essa referência é usada em todos os salvamentos

Se você quer que tudo permaneça em cache para sempre, então você precisa ter um aplicativo que simplesmente seja executado para sempre.Você pode tornar isso um serviço do windows ou um aplicativo normal do windows.
Um serviço do windows é apenas um exe normal que está em conformidade com a API do service manager.Se você quiser fazer um, o visual studio tem um assistente que gera automaticamente algum código de esqueleto para você.Basicamente, em vez de ter um Main método você tem um Service classe com a Run método e tudo o resto é o mesmo.

Você poderia, se quisesse, usar o Agendador de tarefas do windows para agendar suas ações.A maneira como você faria isso é ter seu serviço windows de longa duração em segundo plano que não faz nada.Faça com que ele abra um soquete TCP ou pipe nomeado ou algo assim e apenas sente-se lá.Em seguida, escreva um pequeno "stub" exe que apenas se conecta a este soquete ou pipe nomeado e diz ao aplicativo em segundo plano para acordar.
Isto é, naturalmente, muito mais difícil do que apenas fazer um sleep no seu aplicativo em segundo plano, mas permite que você tenha muito mais controle - você pode alterar o tempo de suspensão sem reiniciar o serviço em segundo plano, executá-lo sob demanda, etc.


Gostaria, no entanto, de considerar a sua concepção.O facto de se confiar num serviço de longa duração constitui um grande ponto de falha.Se o seu aplicativo precisa ser executado por dias, e você tem um único bug que trava-lo, então você tem que começar de novo.Uma arquitetura muito melhor é seguir o modelo Unix, onde você tem pequenos processos que começam, fazem uma coisa e depois terminam (neste caso, processam cada simulação de jogo como seu próprio processo, então se um morre, não leva o processo mestre ou as outras simulações para baixo).

Parece que a principal razão pela qual você está tentando tê-lo de longa duração é armazenar em cache suas consultas de banco de dados.Tem mesmo de o fazer?Na maioria das vezes, os bancos de dados são bastante rápidos (eles têm seus próprios caches, que são muito inteligentes).Um erro comum que vi os programadores cometerem é apenas presumir que algo como um banco de dados é lento e perder muito tempo otimizando quando, na verdade, tudo bem

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top