2017-08-20 1 views
0

Ich habe eine Webisite-Dummy, wo ich eine Aufgabe in einer while(true) Schleife ausführen möchte und ich möchte es für immer laufen. Ich bin in einem Schulprojekt über Fußballwetten und ich brauche diese Art von Cloud-Website, um Spiele und Ergebnisse für mich jeden Tag automatisch zu aktualisieren, sie in die Datenbank einzufügen und E-Mails zu senden, abhängig von den Wetten der Eacher-Nutzer das Spiel oder nicht).Halten Sie den Prozess für immer

Obwohl, ich kann nicht scheinen, es am Leben zu halten. Dies ist mein 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", "[email protected]", "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); 
     } 
    } 

Also, wenn ich die Seite öffnet, wird es aktiv sein und auf die Seite zu laden gehen und die Aufgabe auszuführen. Alles läuft glatt. Aber am nächsten Tag bekomme ich keine Updates für die Datenbank oder E-Mails, wenn ich die Seite nicht wieder öffne, was ich nicht möchte.

Wie kann dies erreicht werden?

Danke für die Hilfe, im Voraus.

+2

Haben Sie cons mit einem Service in Verbindung gebracht? ... Dies ist auch eine Möglichkeit: https://www.hangfire.io/ – Stefan

+0

Hilft https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx Hilfe? – mjwills

+0

[Quartz.net] (https://www.quartz-scheduler.net/) kann auch verwendet werden, um Dinge zu planen. Allerdings müssen Sie AppPool Recycling und den 20-minütigen Schlaf des Pools berücksichtigen. Wenn Sie wirklich alle x Minuten oder in bestimmten Intervallen zuverlässig arbeiten möchten, verwenden Sie einen Dienst oder ein Programm auf dem Server. – VDWWD

Antwort

1

Wie ich im Kommentar erwähnt: Sie sollten erwägen, einen Service, oder vielleicht hängen-Feuer, das ist nach dort Website:

Eine einfache Möglichkeit, die Hintergrundverarbeitung in .NET auszuführen und .NET Kernanwendungen. Kein Windows-Dienst oder separater Prozess erforderlich.

Unterstützt durch persistenten Speicher. Offen und frei für kommerzielle Nutzung.

https://www.hangfire.io/

Es gibt einige einfache Beispiele dort Homepage, wie:

var jobId = BackgroundJob.Schedule(
    () => Console.WriteLine("Delayed!"), 
    TimeSpan.FromDays(7)); 

oder

//recurring CRON 
RecurringJob.AddOrUpdate(
    () => Console.WriteLine("Recurring!"), 
    Cron.Daily); 

CRON schön ist eigentlich für geplante Aufgaben finden https://en.wikipedia.org/wiki/Cron

Hinweis: Wenn Sie Hangfire verwenden, muss der Prozess, der die Instanz erstellt hat, aktiv sein, um die Aufgaben auszuführen. Obwohl der persistente Speicher die Tasks speichert und bei Verzögerung ausführt, wird die Task nicht zum genau angegebenen Zeitpunkt ausgeführt, wenn Ihre Anwendung nicht ausgeführt wird.

Wenn Ihr App-Pool inaktiv ist oder nicht ausgeführt wird, weil er wiederverwendet wurde, wird die Task beim nächsten Aufwärmzyklus Ihrer Website ausgeführt. Dies tritt normalerweise auf, wenn Sie versuchen, auf die Site zuzugreifen.

Wenn dies nicht erwünscht ist, können Sie Ihren Web-Host (IIS) so konfigurieren, dass der Anwendungspool aktiv bleibt oder nach dem Recycling sofort gestartet wird. Das "How to" hängt ein wenig von dem Host ab, den Sie verwenden, aber im Prinzip ist es auf fast jedem System gleich.

Mehr zu diesem Thema:

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

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

oder im schlimmsten Fall: How do I set up my IIS to keep my application alive?

+0

Warte, also bedeutet das, dass der Server darauf schlafen wird? Ich benutze den Somee-Server, habe also keinen Zugriff auf den IIS. Heißt das, dass HangFire dann nicht am Leben bleibt? – taiko

+0

Nun, Sie sollten versuchen, google, dass ich denke. Ich habe selbst eine Zeit lang nicht mit dem Hangfire gearbeitet, während ich damit gearbeitet habe, es hat den App-Pool nicht am Leben erhalten. Vielleicht haben sie das geändert, weil es eine offensichtliche Ergänzung ist. Was es sicherstellt, ist, dass, selbst wenn der App-Pool ausfällt, die verzögerten Jobs laufen, wenn sie wieder zurückkommen. – Stefan

+0

Hier ist, was die Dokumente sagen: http://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html – Stefan

Verwandte Themen