Array
(
)

Windows Service diaparado minuto a minuto

Pjava
   - 04 set 2012

Como eu faço para meu serviço ficar de um em um minuto ou outro intervalo, executando suas tarefas, ou seja, fazendo o método OnStart dele ser executado nesse intervalo?

Pjava
   - 04 set 2012

Abaixo meu código para rodar o serviço. Esse código só funciona quando o serviço é iniciado e depois ele não faz mais nada e deveria a cada minuto enviar um email e executar uma calculadora. Isso é feito no início do serviço. Como eu faço para minuto a minuto ele funcionar? O código da gravação dos logs se torna dispensável, pois está funcionando e nada a ver com a Thread. Como isso funciona?

using System.Threading;
using timer = System.Timers;

namespace GrupoLTM.Servico
{
public partial class Service1 : ServiceBase
{
string Erro = "";
Thread t = null;

timer.Timer tm = new timer.Timer();

List<Domain.Entity.AgendamentoRotina> agendamentos = new List<Entity.AgendamentoRotina>();

public Service1()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
tm.Interval = 60000;
tm.Elapsed += new timer.ElapsedEventHandler(OnElapsedTime);

tm.Enabled = true;

t = new Thread(Executar);
t.Start();
Thread.Sleep(60000);
}

protected override void OnStop()
{
try
{
t.Abort();
}
catch (ThreadAbortException tae)
{
Erro = tae.Message;
GravaLogErro(Erro);
}
}

private void Executar()
{
var rotinas = Repository.Rotina.RetornarTodos();
var _log = Repository.LogAgendamentoRotina.RetornarTodos();

Entity.LogAgendamentoRotina log = null;

foreach (var rotina in rotinas)
{
agendamentos.AddRange(rotina.Agendamentos.FindAll(c => c.DataExecucaoInicial >= DateTime.Now.AddDays(-2) && c.DataExecucaoInicial <= DateTime.Now.AddDays(1)));
}

foreach (var agendamento in agendamentos)
{
if ((agendamento.FrequenciaExecucao.DescricaoFrequencia == "Unica" || agendamento.FrequenciaExecucao.DescricaoFrequencia == "Diario"
|| agendamento.FrequenciaExecucao.DescricaoFrequencia == "Semanal" || agendamento.FrequenciaExecucao.DescricaoFrequencia == "Mensal")
&& agendamento.DataExecucaoInicial > DateTime.Now.AddDays(-2) && agendamento.DataExecucaoInicial < DateTime.Now.AddMinutes(1)
&& agendamento.DataExecucaoFinal <= DateTime.Now.AddDays(5) && agendamento.Ativo == true)
{
try
{
agendamento.Rotina.Executar();
GravaLog();
}
catch (Exception e)
{
Erro = e.Message;
GravaLogErro(Erro);
}
} //if
} //foreach

}

Pjava
   - 07 set 2012

No método OnStart eu fiz assim:

protected override void OnStart(string[] args)
{
while (true)
{
t = new Thread(Executar);
t.Start();
Thread.Sleep(60000);
}
}

Isso está fazendo com que o serviço envie 2,3 ou 4 emails num intervalo de um minuto,quando deveria apenas enviar um e como fazer para executar uma tarefa, somente quando a outra terminar por completo.

Pjava
   - 07 set 2012

Opa, esqueci de relatar outra coisa. Quando eu vou iniciar o serviço, ele dá a mensagem que o serviço não pode ser iniciado e fica com a mensagem iniciando, mas fica funcionando. É nesse cenário que ele envia mais de um email e isso só acontece quando coloco no OnStart o While(true).

Pjava
   - 10 set 2012

Refiz o código e funcionou, mas não como deveria, ou seja, continua não obedecendo o limite de tempo de 1 minuto. Num periodo de 5 minutos, tenho recebido mais de 20 emails, sendo que muitos deles, dentro do mesmo minuto. Isso só acontece com o WS. Se eu colocar um botão e um while, ele faz certinho. Nesse teste, eu recebo 2 emails e executo a calc do windows. Um email se chama Teste e outro se chama DTSX Erro. Bem, às vezes no mesmo minuto, recebo 2 emails de Teste ou de DTSX Erro e não poderia. Deveria acontecer em minutos diferentes. Abaixo meu código adaptado.

OnStart

verificaExecucaoRotina = VerificaExecucaoRotina();

if (!verificaExecucaoRotina)
{
ThreadStart st = new ThreadStart(Executar);
t = new Thread(st);
serviceStarted = true;
t.Start();
}
else
{
Thread.Sleep(60000);
verificaExecucaoRotina = false;
}

Meu método Executar()

private void Executar()
{
while (serviceStarted)
{

var rotinas = Repository.Rotina.RetornarTodos();
var _log = Repository.LogAgendamentoRotina.RetornarTodos();

Entity.LogAgendamentoRotina log = null;

foreach (var rotina in rotinas)
{
agendamentos.AddRange(rotina.Agendamentos.FindAll(c => c.DataExecucaoInicial >= DateTime.Now.AddDays(-9) && c.DataExecucaoInicial <= DateTime.Now.AddDays(1)));
}

foreach (var agendamento in agendamentos)
{
if ((agendamento.FrequenciaExecucao.DescricaoFrequencia == "Unica" || agendamento.FrequenciaExecucao.DescricaoFrequencia == "Diario"
|| agendamento.FrequenciaExecucao.DescricaoFrequencia == "Semanal" || agendamento.FrequenciaExecucao.DescricaoFrequencia == "Mensal")
&& agendamento.DataExecucaoInicial > DateTime.Now.AddDays(-9) && agendamento.DataExecucaoInicial < DateTime.Now.AddMinutes(1)
&& agendamento.DataExecucaoFinal <= DateTime.Now.AddDays(5) && agendamento.Ativo == true)
{
try
{
agendamento.Rotina.Executar();
GravaLog();
}
catch (Exception e)
{
Erro = e.Message;
GravaLogErro(Erro);
}
} //if
} //foreach

if (serviceStarted)
{
Thread.Sleep(new TimeSpan(0, 1, 0));
}