跳到主要內容

關於ASP.NET core的IHostedService的schedule task不會自動執行的問題

最近在測試ASP.NET core上的IHostedService製作的schedule task ,發現了一個tricky的問題。

       問題描述如下:

Startup.cs中的ConfigureServices() 裡我們會加上要重複執行的schedule task (IHostedService),預期網站運行後開始背景執行這些task,但實際在IIS上測試發現兩個問題:

 

1.      schedule task並不會自動執行,除非對網站進行訪問(任何http request),例如開啟首頁。這時那些在ConfigureServices()加入的task才會被建立並且開始運作。

 

2.      如果一直都沒有對網站進行訪問(任何http request),約20分鐘後所有task都會停止,直到下一次網站被訪問(任何http request)才會又開始所有task  

 

基於以上兩點行為,針對第一點,我們的網站必須要每次主機開機都開一次首頁或是任何對網站的request,否則schedule task不會執行。針對第二點,我們需要確保固定時間對網站進行訪問(任何http request),目前的作法是每次task執行時就發個request(如果schedule task本來就會發API request就沒問題)


ASP.NET Core的IHostedService運作行為:

這個問題目前的了解是:以IHostedService製作的schedule task,它的生命週期開始在Web server接收到任何一個http request的時候,而IIS運行Web server時並不會觸發http request,所以schedule task也就不會啟動。再來另一個狀況是,IIS有個預設的idle timeout機制,即使schedule task啟動了,如果一直都沒有對網站進行訪問(任何http request),20分鐘後會將Web server的http實體程序關閉,所以schedule task也就停止了。

非透過IIS的解決方式:

    在Server開機後透過固定開啟網站首頁的方式,讓schedule task啟動,並加入一個schedule task固定每10分鐘對Web server發送一個http request,以確保IIS不會將schedule task停止。

透過IIS的解決方式:

    在IIS管理介面上可以設定,將Web server的行為設成每次server運行時就載入主體程序。經測試可以解決IHostedService製作的schedule task不會自行啟動的問題,另外即使IIS預設的idle timeout時間到了,也會自動重啟新的主體程序,schedule task不會停止。

設定步驟如下:

[設定自動背景執行]

[控制台]-->[程式和功能]-->[開啟或關閉windows功能] à打勾 應用程式初始化

 

如下圖,在IIS管理員中進入[進階設定]

[預先載入已啟用]設為True

 

[應用程式集區],的[進階設定]

 

如下圖,將[啟動模式]設成 AlwaysRunning

 

至此完成設定


留言

這個網誌中的熱門文章

[Python] 以.py檔案產生Windows EXE 執行檔

如何開發能在Windows下執行的Python程式?你當然可以在Windows下安裝Python之後用command line運行你的 .py source code來直接執行程式,但是這方法基本上只適合開發中的程式,或是自己寫好玩只在自己的PC上執行的程式,也許適用。 但若你的需求是要在每個Windows的OS下都可以執行、且是不公開程式碼的,那就必須要將你的 .py source code包裝成EXE執行檔了,下面就介紹如何進行: –下載 auto-py-to-exe-master https://github.com/brentvollebregt/auto-py-to-exe 1. 解壓縮auto-py-to-exe-master.zip到想要的路徑下(路徑不能有空格或".") 2. 開啟Cmd console 到auto-py-to-exe-master路徑下 3. 在console下執行"pip install -r requirements.txt" 4. 在console下執行"python run.py" 運行完畢後就可以選取你要轉成執行檔的 .py 檔案,進行製作。 可參考下面的影片: 產生出來的檔案包含執行檔與其程式中會用到的相關Lib檔案,所以要將整個output資料夾中的檔案一併提取出來 (不要只拿執行檔出來)。 如此你就可以在任意的Windows上執行你的程式了。

[Python] 管理多個執行緒(thread)的運作與結束

在開發應用程式中,幾乎所有的專案都會用到thread,不同的程式語言有不同˙的叫用方法,但都大同小異。Thread的使用上最重要的不是在產生一個thread,而是如何結束一個thread,或是如何結束好幾個threads,以下介紹在Python中如何叫用並管理一或多個thread: 一般來說,create thread如下: def job(): while 1: print("Child thread:", i) time.sleep(1) #In main code thread = threading.Thread.__init__(job) thread.start() 這樣可以開始一個thread執行job()中的動作,但若job中的迴圈是如上範例的無限迴圈,必須要加上能讓其退出的機制: stopped = 0 def job(): global stopped while stopped == 0: print("Child thread:", i) time.sleep(1) #In main code thread = threading.Thread.__init__(job) thread.start() 這樣在主程序先將stopped設成1,再調用 thread.join() 就可以將thread完整關閉並釋放記憶體空間。 多執行續的處理: 基於這樣的方式,下面是進化版本,創建一個thread專用的class,並同時處理多個thread的執行與結束: class EventHandleThread (threading.Thread): def __init__(self, fun, name): threading.Thread.__init__(self) self.name = name self.fun = fun self.stopped = [0] def run(self): self.fun(self.name, self.stopped) print ("Exiting " ...

Visual Studio 軟體開發的授權問題

使用Visual Studio開發各種軟體產品非常的方便,此款地表最強軟體開發工具涵蓋了各種的程式語言。但在授權上需要注意一下,否則很有可能會被微軟收取罰金。         Visual Studio Community可以在任何狀況下使用,但是要商業用途(賣產品)只限個人創作,公司組織的話除非是開放原碼、教育、學術研究,除此之外皆不可使用。 因此公司組織要用Visual Studio做產品的話,一種做法是買一套Professional版本,開發時用 Community 版本,要Release給客戶時用 Professional 或更高級的版本編譯;另一種做法是不考慮轉用更高級版本,那麼一開始就採用 Express 版可以降低未來轉換之困擾。 但需要知道 Express 版少了許多功能(例如 Code Coverage、Profiling ...),並且從2019開始微軟不再推出Express版本,也意味著沒有"公司組織免費使用Visual Studio開發產品"的選項了。 微軟雖然不再推出Express版本,但有另一個免費的IDE工具VS code,也可用來開發軟體,只是相對來說Visual Studio只稱得上是一個程式編輯器,如果要在VS code上開發如Winform的程式,就要使用第三方的工具了,以下提供幾個VS code上開發的連結: VS code上開發Winform https://ironmansoftware.com/building-a-windows-form-app-with-powershell-in-vs-code/ VS code上開發ASP.NET core https://blog.johnwu.cc/article/asp-net-core-3-starting.html