保持流程永远运行 [英] Keep process running forever

查看:68
本文介绍了保持流程永远运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个虚拟网站,我想在其中运行 while(true)循环中的任务,并且希望它永远运行.我在一个有关足球投注的学校项目中,我需要这个(某种)云网站来每天自动为我更新游戏和结果,将它们插入数据库并发送电子邮件,具体取决于每个用户的投注(如果他们获得了积分)游戏).

I have a dummy webisite where I want to run a task in a while(true) loop and I want it to run forever. I'm in a school project about soccer bets and I need this (sort of) cloud website to automatically update games and results for me everyday, insert them in the database and send emails, depending on eacher users bets (if they gots points in the game or not).

尽管如此,我似乎无法保持它的生命.这是我的代码:

Although, I can't seem to keep it alive. This is my code:

 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);
        }
    }

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

So, if I open the page, it will be active and will go to the page load and run the task. Everything goes smoothly. But on the next day, I don't get any updates to the database or emails unless I open the page again, which is not what I want.

如何实现?

感谢您的帮助.

推荐答案

正如我在评论中所提到的:根据该网站,您应该考虑使用一项服务,或者可能是挂火":

As I mentioned in the comment: You should consider using a service, or perhaps hang-fire which is, according to there website:

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

An easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process required.

以持久性存储为后盾.开放供商业使用.

Backed by persistent storage. Open and free for commercial use.

https://www.hangfire.io/

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

There are some easy examples on there homepage, like:

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

CRON is nice actually, for scheduled tasks, see https://en.wikipedia.org/wiki/Cron

注意:如果您使用的是hangfire,则创建实例的进程必须处于活动状态才能执行任务.尽管永久性存储会保存任务并在延迟时执行任务,但是如果您的应用程序未在运行,则该任务将不会在给定的确切时间执行.

note: if you are using hangfire, the process which created the instance must be alive to execute the tasks. Although the persistent storage saves the tasks and execute them if delayed, if your application is not running, the task will not be executed at the exact given moment.

对于您来说,如果您的应用程序池由于已被回收而处于闲置状态或未运行,则该任务将在您网站的下一个预热周期执行,这通常是在您尝试访问该网站时发生的.

In your case, if your app-pool is idle or not running because it has been recycled, the task will execute at the next warmup cycle of your website, this typically occurs when you try to access the site.

如果这是不需要的,则可以配置Web主机(IIS)以使应用程序池保持活动状态,或在回收后立即启动.如何"取决于您使用的主机,但基本上在几乎每个系统上都是相同的.

If this is unwanted, you can configure your web-host (IIS) to keep the application pool alive or do an immediate startup after recycling. The "how to" depends a bit on the host you are using, but basically it's the same on almost every system.

关于此事的更多信息:

IIS https://serverfault.com/questions/333907/我应该做什么才能确保iis不会回收我的应用程序

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

或在最坏的情况下:如何将IIS设置为使我的应用程序保持活动状态?

这篇关于保持流程永远运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆