2009-07-29 29 views
2

我有一個使用SQL持久性的Windows Workflow實例,它承載於Web運行時,因爲工作流由ASP.NET表單提交啓動。它大部分時間運行良好,但我注意到我必須踢東西的情況:Windows工作流程:爲什麼他們被困在持久性中?

我注意到nextTimer已經過時了,甚至幾個小時。有時,持久性數據庫中的ownerID和ownedUntil字段爲空,有時不是。 「解鎖」和「封鎖」字段始終都是「1」。

...然後工作流運行時不會選擇它備份,直到我填充「所有者」字段,如果它們被填充並通過循環啓動應用程序池,並且事情繼續進行之後大部分。沒有任何錯誤(我已經嘗試了/抓住所有的東西,並且寫出任何捕獲到跟蹤文件中的東西),所以不是這樣。

導致持久性的延遲活動都設置爲一分鐘,運行時的擁有持續時間也爲60秒。它被卡住的代碼應該總是不到一分鐘。

正如我寫這篇文章,我很好奇,如果應用程序池/應用程序域的再循環造成它......當工作流嘗試調用運行時的任何方法時,它正忙於旋轉應用程序域/池,可能會在60秒的擁有時間內泄漏。這聽起來很合理,會導致它不能正常補充水分?

除了側軌,有什麼會導致這種行爲,我看到了?我不想每天通過阻止卡住的工作流來保持運行時間。

回答

7

它很可能是應用程序域的回收是你的問題的很大一部分。一旦最後一次請求完成,IIS將回收一個AppDomain。但是,它不會將代碼作爲該請求的一部分在另一個線程上運行。這是在IIS中託管時使用ManualWorkflowSchedulerService的主要原因之一。但是,當您使用活動計時器選項時,它仍然使用後臺線程來執行工作流活動。

此外,請確保您在工作空閒後立即卸載工作流程。最簡單的方法是使用SqlWorkflowPersistenceService上的UnloadOnIdle設置。

PersistenceService將檢查擁有過期所有權的工作流程,但僅在啓動時進行檢查。因此,最有可能重新啓動IIS輔助進程也將重新啓動舊的工作流程,而無需任何額外的工作。但是,正因爲這是新問題.....只是清理舊的所有權也應該這樣做。在這種情況下,PersistenceService應該在下一次重新加載工作流程。唯一的竅門是知道哪個runitme ID是舊的,哪個不是(保存該值的屬性不公開)。

另一件需要確認的事情是重新加載IIS工作進程。如果沒有這樣做,就沒有WF運行時,所以它不能檢查過期的定時器。這聽起來像你有這個覆蓋,但以防萬一。

+0

優秀的寫作,我會盡可能多地嘗試,並報告回來。 – Chris 2009-07-29 21:21:50

+1

標記爲已接受,因爲它覆蓋了很多地面,感謝您的信息!它最終成爲擁有時間。我調高了instanceOwnershipDuration,以便爲每個加載的活動嘗試執行的任何操作都完全執行,並且從那以後它一直沒有出現問題。 – Chris 2009-08-07 15:26:42

1

你是否檢查過你的db和web服務器上的時鐘(如果它們不是同一臺服務器)?我之前在工作流程中遇到過類似問題,根本原因是數據庫和Web服務器時鐘不同步。

+0

我沒有想到這一點,但檢查,他們在第二個同步。好主意,但謝謝! – Chris 2009-07-29 17:52:48

2

工作流實例被鎖定到一個運行時(所以多個工作流運行時可以共享一個數據庫,而不需要同時處理實例)。當AppDomain中回收,運行時應該停止,導致情況變得解鎖

這可能是多餘的,我沒有檢查這一點,但它在解鎖工作流實例幫助:

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