2017-09-16 25 views
1

我有哪些,其核心是通過調用類似方法運行幾個永無止境的循環服務:如何在C#中的無處不在的任務上最好地實現看門狗?

public async Task DoStuffPeriodically(CancellationToken token); 

他們通過調用調用:

var tokenSource = new CancellationTokenSource(); 
var stuffTask = DoStuffPeriodically(tokenSource.token); 

現在,這將永遠運行,只有在以不同的方法取消令牌並致電stuffTask.Wait()時纔會停止。 只有我們是否會收到DoStuffPeriodically可能會播放的任何異常。

這是可能(但不太可能),這實際上DoStuffPeriodically兩罰全中,這意味着我指望循環不再運行。我打算通過在主線程中定期檢查stuffTask.IsFaulted並引發異常(這將強制服務重新啓動)中的循環來監視它。

有沒有更好的方式來做到這一點?我不想輪詢任務狀態,如果無論如何要從它那裏得到一個我不知道的回調。

謝謝!

+0

您的用例看起來更像一個'Timer',而不是像在後臺旋轉的單個線程那樣。另一個不錯的選擇是使用專門爲這類任務設計的庫,如[Quartz.net](https://github.com/quartznet/quartznet)或[FluentScheduler](https://github.com/ fluentscheduler/FluentScheduler)。這兩個選項都具有更強大的異常處理能力,並且在發生異常時不會停止定期工作。 –

+0

@Miquel出於某種原因剛剛進入該線程。我們在該場景中廣泛使用了'Timer',這有點違背了大多數異步/等待的使用 - 但它恰當地捕捉錯誤並提供更好的保證。來自德國的老朋友的問候;-) –

+0

@ThomasJungblut我們已經去見過Kapol的想法並使用了ContinueWith,似乎目前運作良好!另外,真的很高興聽到你:) – Miquel

回答

3

您可以使用Task.ContinueWith,將TaskContinuationOptions.OnlyOnFaulted傳遞給continuationOptions參數。只有當先行者拋出未處理的異常時,纔會觸發回調。在這個回調中,你可以設置一些標誌或拋出異常。

stuffTask.ContinueWith(t => { throw new Exception(); }, 
    null, 
    TaskContinuationOptions.OnlyOnFaulted); 
+0

哦,輝煌!我沒有想到這一點。謝謝! – Miquel