Domanda

Ho un'istanza di Windows Workflow che utilizza la persistenza SQL, essendo ospitata nel runtime Web, poiché i flussi di lavoro sono avviati da invii di moduli ASP.NET. Funziona alla grande per la maggior parte del tempo, ma ho notato casi in cui devo calciare le cose:

Ho notato che il prossimo timer è in ritardo, anche da ore. A volte i campi ownerID e ownedUntil sono nulli nel database di persistenza, a volte no. & Quot; sbloccato " e "bloccato" i campi sono sempre entrambi " 1 " ;.

... e quindi il runtime del flusso di lavoro non lo riprende fino a quando non annullo il "proprietario" campi se sono popolati e lanciano il pool di applicazioni con un riciclo, e le cose procedono bene dopo quello per la maggior parte. Non ci sono errori (ho provato / catturato blocchi intorno a tutto e ho scritto tutto catturato in un file di traccia), quindi non è così.

Le attività di ritardo che causano la persistenza sono tutte impostate su un minuto e anche la durata della proprietà per il runtime è di 60 secondi. Il codice su cui si blocca dovrebbe sempre richiedere meno di un minuto.

Mentre scrivo, sono curioso di sapere se il riciclo del pool di app / dominio dell'app lo sta causando ... quando il flusso di lavoro tenta di chiamare qualsiasi metodo in fase di runtime, è impegnato a girare il dominio / pool di app e potrebbe perdita per la durata della proprietà di 60 secondi. Sembra abbastanza plausibile da remoto, e non lo farebbe reidratare correttamente?

Escludendo quella deviazione, che cosa potrebbe causare questo comportamento che sto vedendo? Non voglio fare da babysitter al runtime ogni giorno deselezionando i flussi di lavoro bloccati.

È stato utile?

Soluzione

È molto probabile che il riciclo del dominio dell'app sia una grande parte del tuo problema. IIS riciclerà un AppDomain non appena termina l'ultima richiesta. Tuttavia, non vede il codice in esecuzione su un altro thread come parte di tale richiesta. Questo è uno dei motivi principali per l'utilizzo di ManualWorkflowSchedulerService durante l'hosting in IIS. Ma quando si utilizza l'opzione timer attivi, viene comunque utilizzato un thread in background per eseguire le attività del flusso di lavoro.

Assicurati inoltre di scaricare i flussi di lavoro non appena diventano inattivi. Il modo più semplice per farlo è utilizzare l'impostazione UnloadOnIdle su SqlWorkflowPersistenceService.

PersistenceService verifica la presenza di flussi di lavoro con una proprietà scaduta ma solo all'avvio. Quindi molto probabilmente il riavvio del processo di lavoro IIS riavvierà anche i vecchi flussi di lavoro senza alcun lavoro aggiuntivo. Ma dato che questo è il caso di nuovi problemi ..... Anche eliminare la vecchia proprietà dovrebbe fare il trucco. In tal caso, PersistenceService dovrebbe ricaricare i flussi di lavoro alla volta successiva. L'unico trucco è sapere quale ID runitme è vecchio e quale no (la proprietà che detiene il valore non è pubblica).

Un'altra cosa di cui accertarsi è che il processo di lavoro IIS venga ricaricato. Se ciò non viene fatto, non esiste un runtime WF, quindi non è possibile verificare la presenza di timer scaduti. Sembra che tu abbia questo coperto, ma per ogni evenienza.

Altri suggerimenti

Le istanze del flusso di lavoro sono bloccate su un runtime (quindi più runtime del flusso di lavoro possono condividere un database senza che entrambe le istanze vengano gestite). Quando AppDomain ricicla, è necessario arrestare il runtime, facendo sbloccare le istanze

Potrebbe essere ridondante, non l'ho verificato, ma mi ha aiutato a sbloccare le istanze del flusso di lavoro:

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

Hai controllato l'orologio sul tuo db e server web (se non sono lo stesso server)? Ho avuto problemi simili in precedenza con il flusso di lavoro e la causa principale era che gli orologi del db e del web server non erano sincronizzati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top