2016-10-05 4 views
0

Ich habe eine harte Zeit mit diesem.Aufgabe hört auf, an anderer Umgebung zu arbeiten

Also in meinem asp.net Anwendung ein solches Verfahren gibt es:

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    Task.Run(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

private void performCopying(CopyCCRequest request) 
{ 
    using (Repository = new myDbContext()) 
    { 
     // do some initial action 
     try 
     { 
     // in general it looks like below 
      foreach(var children in father) 
      { 
       var newChildren = chldren.Copy(); 
       Repository.Childrens.Add(newChildren); 

       foreach (var grandchldren in children.grandchildrens) 
       { 
        var newGrandchildren = grandchldren.Copy(); 
        newGrandchildren.Parent = newChildren; 

        Repository.Grandchildrens.Add(newGrandchildren); 
       } 

       Repository.SaveChanges(); 
      } 
     } 
     catch (Exception ex) 
     { 
      // log that action failed 

      throw ex; 
     } 
    } 
} 

Dieses Verfahren und alle anderen (es gibt einige ähnliche) auf meinem lokalen Computer ohne Probleme wie geplant funktioniert.

Leider auf einer anderen Umgebung diese Methoden versagen:

  • kleinere Teile von Daten Kopieren funktioniert. Wenn jedoch mehr als 3000 Objekte bearbeitet werden müssen, schlägt die Methode fehl.
  • Hauptanwendung reagiert dennoch richtig.
  • Die meisten Operationen sind gut erledigt (die meisten Daten werden kopiert und in der Datenbank gespeichert)
  • Die Anwendung gibt keinen catch-Block ein. Anweisungen für fehlgeschlagenes Kopieren werden nicht ausgeführt. Ausnahme wird nicht durch den Fehlerhandler abgefangen (BTW, ich weiß standardmäßig die App kann keine Ausnahmen von unabhängigen Task abfangen, schrieb ich meine Handler, so wird es schaffen, dies zu tun).
  • IIS-Worker-Prozess scheint über 300 MB und 0% Prozessorleistung nach dem Beenden des Kopiervorgangs zu übernehmen. Mehr als die Hälfte des Arbeitsspeichers auf dem Server ist noch frei.
  • Ich schaute in Windows-Ereignisprotokoll, aber habe nichts gefunden.

Haben Sie Vorschläge, wie ich mit diesem Problem umgehen kann?

Antwort

1

Sie können keine zuverlässigen "Fire and Forget" -Tasks in IIS ausführen. Wenn die Site nicht bedient wird, wird der Anwendungspool nach einer Weile auf AppDomain heruntergefahren.

Zwei Optionen zu verwenden sind:

HostingEnvironment.QueueBackgroundWorkItem IIS, Ihnen zu sagen Hintergrund Arbeit tun. Dadurch wird der Server über die Arbeit informiert und das Herunterfahren wird so lange wie möglich verzögert (standardmäßig maximal 90 Sekunden), bevor der Prozess beendet wird.

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    HostingEnvironment.QueueBackgroundWorkItem(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

Eine weitere Option ist eine 3rd-Party-Bibliothek zu verwenden, das zu tun Hintergrund arbeitet in IIS wie Hangfire.io ausgelegt ist, wird dies einen Dienst innerhalb von IIS ausführen, der die Arbeit macht und versucht, die Instanz am Leben, bis die Arbeit zu halten erledigt. Sie können Hangfire auch so konfigurieren, dass es als separater Prozess ausgeführt wird, sodass Sie nicht auf die Lebensdauer der IIS-Instanz angewiesen sind.

public CopyResponse thirdStage(CopyRequest request) 
{ 
    CopyCCResponse response = new CopyCCResponse(); 

    BackgroundJob.Enqueue(() => 
    { 
     performCopying(request); 
    }); 

    return response; 
} 

Hinweis, hangfire mit einem separaten Prozess verwenden, können Sie benötigt ein wenig Redesign performCopying(CopyCCRequest request) zu tun zu laufen von einem separaten Prozess zu unterstützen, ist es aus dem Innern der IIS-Instanz verwenden, sollte keine Änderungen erforderlich.

+0

Vielen Dank für Ihre Antwort. Sie haben geschrieben, dass 'HostingEnvironment.QueueBackgroundWorkItem'" das Herunterfahren so lange wie möglich verzögern wird ". Es bedeutet, dass es immer noch keine zuverlässige Lösung ist, um große und lange Hintergrundprozesse zu starten. Habe ich recht? –

+0

Ja. Wenn Sie erwarten, dass der Prozess länger als 90 Sekunden dauert, ist ein hangfire.io die bessere Option. Die Ausführung als separater Dienst ist die beste Option, erfordert jedoch möglicherweise Codeänderungen, um Klassen serialisieren zu können. Es läuft auch im Prozess, aber ich weiß nicht, wie viel mehr Zeit als 90 Sekunden es Ihnen geben wird. Könnte 91 Sekunden sein, könnte 4 Tage sein, ich weiß es einfach nicht –

Verwandte Themen