Question

J'ai une instance de flux de travail Windows utilisant la persistance SQL, hébergée dans l'exécution Web, car les flux de travail sont démarrés par les envois de formulaires ASP.NET. Il fonctionne très bien la plupart du temps, mais j'ai remarqué des cas où je devais donner des coups de pied:

Je remarque que le prochain minuteur a pris du retard, même par heures. Parfois, les champs ownerID et ownUntil sont nuls dans la base de données de persistance, parfois non. Le " débloqué " et " bloqué " les champs sont toujours les deux "1".

... et l'exécution du flux de travail ne le récupère pas tant que je n'ai pas annulé le "propriétaire" des champs s'ils sont remplis et si le pool d'applications est recyclé, et tout se passe bien après. Il n’ya pas d’erreurs (j’ai essayé / attrapé des blocs autour de tout et écrit tout ce qui est pris dans un fichier de trace), donc ce n’est pas ça.

Les activités de retard à l'origine de la persistance sont toutes définies sur une minute et la durée de possession du moteur d'exécution est également de 60 secondes. Le code sur lequel il reste bloqué devrait toujours prendre moins d’une minute.

Au moment où j'écris ces lignes, je suis curieux de savoir si des recyclages du pool d'applications / du domaine d'applications en sont la cause ... lorsque le flux de travail tente d'appeler une méthode du processus d'exécution, il est occupé à lancer le domaine d'applications / le pool et risque de fuite sur la durée de propriété de 60 secondes. Ce son est vraisemblablement plausible et est-ce que cela ne le réhydratera pas correctement?

Sauf cette déviation, qu'est-ce qui pourrait causer ce comportement que je constate? Je ne veux pas garder le runtime tous les jours en décollant les flux de travail bloqués.

Était-ce utile?

La solution

Il est fort probable que le recyclage du domaine des applications constitue une part importante de votre problème. IIS recyclera un AppDomain dès que la dernière requête est terminée. Cependant, il ne voit pas le code s'exécuter sur un autre thread dans le cadre de cette requête. C’est l’une des principales raisons d’utiliser ManualWorkflowSchedulerService lors de l’hébergement dans IIS. Mais lorsque vous utilisez l’option timers actifs, il utilise toujours un fil d’arrière-plan pour exécuter les activités de workflow.

Veillez également à décharger les flux de travail dès qu’ils deviennent inactifs. Le moyen le plus simple consiste à utiliser le paramètre UnloadOnIdle sur SqlWorkflowPersistenceService.

PersistenceService recherche les flux de travail dont la propriété a expiré, mais uniquement au moment du démarrage. Il est donc probable que le redémarrage du processus de travail IIS redémarre également les anciens flux de travail sans travail supplémentaire. Mais comme c’est le cas de nouveaux problèmes ..... Il suffit également de nettoyer l’ancienne propriété. Dans ce cas, PersistenceService doit simplement recharger les flux de travail à la prochaine fois. La seule astuce consiste à savoir quel ID d’exécution est ancien et lequel n’est pas (la propriété contenant la valeur n’est pas publique).

Une autre chose à vérifier est que le processus de travail IIS est rechargé. Si ce n'est pas fait, il n'y a pas d'exécution WF, il ne peut donc pas vérifier les minuteries expirées. On dirait que vous avez couvert cela, mais juste au cas où.

Autres conseils

Les instances de flux de travail sont verrouillées sur un environnement d'exécution (de sorte que plusieurs environnements d'exécution de flux de travail puissent partager une base de données sans que les instances ne soient gérées par les deux). Lorsque l'AppDomain est recyclé, le runtime doit être arrêté, ce qui entraîne le déverrouillage des instances.

Cela peut être redondant, je n'ai pas vérifié cela, mais cela a aidé à déverrouiller les instances de flux de travail:

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

Avez-vous vérifié l'horloge sur vos serveurs de base de données et Web (s'ils ne sont pas le même serveur)? J'ai déjà eu des problèmes similaires avec le flux de travail et la cause principale était que les horloges de la base de données et du serveur Web n'étaient pas synchronisées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top