安全退出,收到退出指令后, 讓所有線程安全執行完在退出。測試環境Ubuntu. Daemon和普通的console都測試, 看Ubuntu在退出是是否等待Console執行完。
起作用的是另一個事件
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading
Main方法中,我把三類事件捕捉,看哪個起作用
這是我們的等待退出邏輯,在wile循環結束后,又等待5秒,是為了讓日志輸出完,根據需要調整
這是模擬一個起動線程的類,線程類的方法如下:
可以看到,當CancellationTokenSource被請求退出時,會break while(true)循環,上面我們有個等待退出的方法中,有個等待5秒,其實就是為了這里的Log.輸出日志。這個只是為了展示,我們的確是待一個循環完成后才安全退出的,如果實際操作中不需要輸出日志,也就不用等待5秒了。
再詳細請參看一下代碼
下面看一下各環境運行情況
windows vs 調試狀態
運行起來,點右上角的X號關閉
結果如下:
下面看一下docker中。
Dockfile如下:
注,我上面有apt-get install procps,是為了演示用的,為了在container安裝ps命令,方便查看各個進程的pid.
進入container,試一下console方式的運行和結束
再開一個終端,查看container內的進程
PID1就是 run container 的主進程,另一個PID34就是我們console啟動的進程,我們先試一下kill console進程的結果
生成了日志,我們把日志拿出來看一下,因為我沒有裝vi/vim,我給copy到宿主機看
OK,下面再試一下kill Container怎么樣。
先進container刪掉日志,看kill container會不會生成。
可見用這樣直接Kill 方式不行。再試另一種方式
這次有日志了
是我們要的結果。
再看一下docker kill 的help 發現上面我們kill 沒有發信號,所以失敗了。再試一次
看到有日志了,我再拷出來看一下對不對
可以看到沒問題 了。
以上就是所有的測試過程和結果。記錄一下,備忘。
真正起作用的,是
1 System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (ctx) => 2 { 3 Log.Information("Closing"); 4 System.Console.WriteLine("Closing"); 5 WaitThreadExit(); 6 };
結束,謝謝觀賞。
追加:
https://docs.microsoft.com/en-us/windows/console/handlerroutine?redirectedfrom=MSDN
https://docs.microsoft.com/zh-cn/dotnet/api/system.appdomain.processexit?view=netcore-3.1
在windows 控制台,直接點右上角的X,還是不行,因為默認的退出時間最多為5秒