我有一个虚拟网站,我希望在while(true)
循环中运行任务,我希望它永远运行。我正在一个关于足球投注的学校项目,我需要这个(某种)云网站每天自动更新游戏和结果,将它们插入数据库并发送电子邮件,这取决于eacher用户的赌注(如果他们有点数)游戏与否)。
虽然,我似乎无法保持活力。这是我的代码:
private static string LigacaoBD = @"connectionString";
private static ApiMethods sportRadar = new ApiMethods();
private static Jogo jogo = new Jogo(LigacaoBD);
private static List<SportRadar.ClassesCliente.Jogo> jogos;
private static List<SportRadar.ClassesCliente.Competicao> competicoes;
protected void Page_Load(object sender, EventArgs e)
{
// Iniciates a new asynchronous task
Task.Factory.StartNew(() => Actualizacoes());
}
public void Actualizacoes()
{
bool verif = true;
while (true)
{
// Time in which I want the task to run the task on the method
if (DateTime.UtcNow.ToLocalTime().Hour == 1 && DateTime.UtcNow.ToLocalTime().Minute == 30 && DateTime.UtcNow.ToLocalTime().Second == 0)
verif = true;
// quando voltar a ficar online será actualizar.
if (verif)
{
// I want the games 7 days from now
DateTime dt = new DateTime(DateTime.UtcNow.ToLocalTime().Year, DateTime.UtcNow.ToLocalTime().Month, DateTime.UtcNow.ToLocalTime().Day + 7);
// This is due to the providers limitation to trial accounts
Thread.Sleep(1000);
// Makes the request for the tournaments to the API
competicoes = sportRadar.Competicoes();
Thread.Sleep(1000);
// Makes the request for the daily schedules to the API
jogos = sportRadar.JogosDoDia(dt);
// Saves each game in each tournament to the database
foreach (SportRadar.ClassesCliente.Jogo j in jogos)
{
foreach (SportRadar.ClassesCliente.Competicao c in competicoes)
if (j.Id_Torneio == c.Id)
{
jogo.Guardar(j.Clube_Casa, j.Clube_Visitante, c.Nome, c.Pais, j.Data);
break;
}
}
// I want the results from the day before
dt = new DateTime(DateTime.UtcNow.ToLocalTime().Year, DateTime.UtcNow.ToLocalTime().Month, DateTime.UtcNow.ToLocalTime().Day-1);
Thread.Sleep(1000);
// Makes the request for the daily results to the API
jogos = sportRadar.ResultadosDoDia(dt);
// Updates the results on the database and sends e-mails according to the points aquried but each user
foreach (SportRadar.ClassesCliente.Jogo j in jogos)
{
foreach (SportRadar.ClassesCliente.Competicao c in competicoes)
if (j.Id_Torneio == c.Id)
{
List<Utilizador> utilizadores = jogo.AlterarResultado(j.Clube_Casa, j.Clube_Visitante, c.Nome, c.Pais, j.Data, j.Golos_Casa, j.Golos_Visitante);
if (utilizadores.Count > 0)
{
foreach (Utilizador u in utilizadores)
Verificacoes.EnviarEmail("smtp.live.com", "betmagnum@hotmail.com", "Senha098!", u.Email,
"BetMagnum - Ganhou pontos num jogo!", "Parabéns, " + u.Nickname + ". Ganhou " + u.Pontuacao + " pontos no jogo " +
j.Clube_Casa + " - " + j.Clube_Visitante + ".<br/><br/>Resultado do jogo:<br/>" +
j.Clube_Casa + " " + j.Golos_Casa + " - " + j.Golos_Visitante + " " + j.Clube_Visitante + "<br/><br/>" +
"Pontos ganhos: "+u.Pontuacao, 587);
}
break;
}
}
verif = false;
}
Thread.Sleep(1000);
}
}
因此,如果我打开页面,它将处于活动状态,并将转到页面加载并运行任务。一切顺利。但是第二天,我没有得到任何数据库或电子邮件的更新,除非我再次打开页面,这不是我想要的。
如何实现这一目标?
提前感谢您的帮助。
答案 0 :(得分:1)
正如我在评论中所提到的:根据网站的说法,您应该考虑使用服务,或者也许是挂机:
在.NET和.NET Core应用程序中执行后台处理的简便方法。无需Windows服务或单独的流程。
以持久存储为后盾。开放和免费用于商业用途。
主页上有一些简单的例子,例如:
var jobId = BackgroundJob.Schedule(
() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays(7));
或
//recurring CRON
RecurringJob.AddOrUpdate(
() => Console.WriteLine("Recurring!"),
Cron.Daily);
CRON实际上很不错,对于计划任务,请参阅https://en.wikipedia.org/wiki/Cron
注意:如果您正在使用hangfire,则创建实例的进程必须处于活动状态才能执行任务。尽管持久存储会保存任务并在延迟时执行它们,但如果您的应用程序未运行,则该任务将不会在确定的时刻执行。
在您的情况下,如果您的应用程序池因为已被回收而空闲或未运行,则该任务将在您网站的下一个预热周期执行,这通常发生在您尝试访问该站点时。
如果这是不需要的,您可以配置Web主机(IIS)以使应用程序池保持活动状态或在回收后立即启动。 &#34;如何&#34;取决于您使用的主机,但基本上它几乎在每个系统上都是相同的。
关于此事的更多信息:
IIS https://technet.microsoft.com/en-us/library/cc753179(v=ws.10).aspx
或在最坏的情况下: How do I set up my IIS to keep my application alive?