让进程永远运行

时间:2017-08-20 11:50:29

标签: c# asp.net sql-server

我有一个虚拟网站,我希望在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);
        }
    }

因此,如果我打开页面,它将处于活动状态,并将转到页面加载并运行任务。一切顺利。但是第二天,我没有得到任何数据库或电子邮件的更新,除非我再次打开页面,这不是我想要的。

如何实现这一目标?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

正如我在评论中所提到的:根据网站的说法,您应该考虑使用服务,或者也许是挂机:

  

在.NET和.NET Core应用程序中执行后台处理的简便方法。无需Windows服务或单独的流程。

     

以持久存储为后盾。开放和免费用于商业用途。

https://www.hangfire.io/

主页上有一些简单的例子,例如:

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://serverfault.com/questions/333907/what-should-i-do-to-make-sure-that-iis-does-not-recycle-my-application

IIS https://technet.microsoft.com/en-us/library/cc753179(v=ws.10).aspx

或: https://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive

或在最坏的情况下: How do I set up my IIS to keep my application alive?