2 Stimmen

Windows-Workflow: Warum bleiben sie in der Persistenz hängen?

Ich habe eine Windows-Workflow-Instanz, die SQL-Persistenz verwendet und in der Web-Laufzeit gehostet wird, da die Workflows durch ASP.NET-Formularübertragungen gestartet werden. Die meiste Zeit läuft es prima, aber ich habe festgestellt, dass es Fälle gibt, in denen ich Dinge abbrechen muss:

Ich stelle fest, dass der nextTimer weit überfällig ist, sogar um Stunden. Manchmal sind die Felder ownerID und ownedUntil in der Persistenzdatenbank null, manchmal nicht. Die Felder "unlocked" und "blocked" sind immer beide "1".

...und dann die Workflow-Laufzeit nicht abholen es wieder, bis ich null out die "Eigentümer" Felder, wenn sie ausgefüllt sind und treten Sie die Anwendung-Pool mit einem recycle, und die Dinge gehen entlang gerade fein nach, dass zum größten Teil. Es gibt keine Fehler (ich habe Try/Catch-Blöcke um alles und schreiben Sie alles gefangen in eine Trace-Datei), so dass es nicht ist.

Die Verzögerungsaktivitäten, die die Persistenz verursachen, sind alle auf eine Minute eingestellt, und die Besitzdauer für die Laufzeit beträgt ebenfalls 60 Sekunden. Der Code, an dem er hängen bleibt, sollte immer weniger als eine Minute dauern.

Wie ich dies schreibe, bin ich neugierig, wenn Rezyklen der app-Pool/App-Domäne es verursachen... wenn der Workflow versucht, welche Methode in der Laufzeit aufrufen, ist es beschäftigt Spinning bis die app-Domäne/Pool und könnte über die 60 Sekunden Besitzdauer lecken. Das klingt im Entferntesten plausibel, und würde das dazu führen, dass es nicht richtig rehydrieren?

Abgesehen von diesem Ablenkungsmanöver, was könnte dieses Verhalten, das ich sehe, verursachen? Ich möchte nicht jeden Tag auf die Runtime aufpassen, indem ich steckengebliebene Workflows auftrenne.

8voto

Maurice Punkte 27462

Es ist sehr wahrscheinlich, dass das Recycling der App-Domäne einen großen Teil des Problems ausmacht. IIS wird eine AppDomain recyceln, sobald die letzte Anfrage beendet ist. Er sieht jedoch nicht, dass Code auf einem anderen Thread als Teil dieser Anforderung läuft. Das ist einer der Hauptgründe für die Verwendung des ManualWorkflowSchedulerService beim Hosting im IIS. Wenn Sie jedoch die Option aktive Zeitgeber verwenden, wird immer noch ein Hintergrund-Thread zur Ausführung von Workflow-Aktivitäten verwendet.

Stellen Sie außerdem sicher, dass Sie Workflows entladen, sobald sie inaktiv werden. Am einfachsten geht das mit der Einstellung UnloadOnIdle des SqlWorkflowPersistenceService.

Der PersistenceService prüft auf Workflows mit abgelaufenen Eigentumsrechten, allerdings nur beim Start. Daher wird ein Neustart des IIS-Arbeitsprozesses höchstwahrscheinlich auch alte Workflows ohne zusätzlichen Aufwand neu starten. Da es sich aber um neue Probleme handelt..... Das Löschen der alten Eigentümerschaft sollte ebenfalls ausreichen. In diesem Fall sollte der PersistenceService die Workflows beim nächsten Mal einfach neu laden. Der einzige Trick besteht darin, zu wissen, welche Runitme-ID alt ist und welche nicht (die Eigenschaft, die den Wert enthält, ist nicht öffentlich).

Außerdem muss sichergestellt werden, dass der IIS-Arbeitsprozess neu geladen wird. Wenn dies nicht geschieht, gibt es keine WF-Laufzeit, so dass er nicht auf abgelaufene Timer prüfen kann. Es klingt, als ob Sie dies abgedeckt haben, aber nur für den Fall.

2voto

Tundey Punkte 2825

Haben Sie die Uhr auf Ihrem Datenbank- und Webserver überprüft (wenn es sich nicht um denselben Server handelt)? Ich hatte schon einmal ähnliche Probleme mit Arbeitsabläufen, und die Hauptursache war, dass die Uhren von Datenbank und Webserver nicht synchronisiert waren.

2voto

Sander Rijken Punkte 21069

Workflow-Instanzen sind an eine Laufzeit gebunden (so dass mehrere Workflow-Laufzeiten eine Datenbank gemeinsam nutzen können, ohne dass die Instanzen von beiden bearbeitet werden). Wenn die AppDomain recycelt wird, sollte die Runtime gestoppt werden, wodurch die Instanzen entsperrt werden

Dies könnte überflüssig sein, ich habe es nicht überprüft, aber es half bei der Freischaltung der Workflow-Instanzen:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X