2013-06-28 73 views
1

我正在編寫一個多線程應用程序。這是我的情況。如何確保任何線程不會無限期地等待某些東西?

我從數據庫中抓取了一千條記錄。將它分成5個塊的列表對象。並創建5個線程來處理它們。我這樣做同樣的事情,每分鐘,直到我在數據庫中剩餘

Task.Factory.StartNew(() => ProcessRecords(listRecords)) 

內ProcessRecords方法記錄,有一個小的數據庫更新和一些發送郵件發生。 (我使用System.Net.Mail電子郵件和不使用數據庫操作的任何ORM)

現在我很擔心,一個線程可能不會因爲一些未知的問題完成。在這種情況下會發生什麼?比方說一個進程(甚至更多)不斷等待數據庫中的死鎖或者什麼,我的應用程序會發生什麼。它將繼續添加新的線程與新的記錄集,而一些永不結束的線程。在這種情況下,我如何實現類似超時的事情?

我要運行這個進程,終止它在5分鐘內,如果它是不能夠完成它。

+0

無法修改[MSDN上的示例代碼](http://msdn.microsoft.com/library/dd537610.aspx)以滿足您的要求嗎? –

+0

在開始新線程之前,我不想等待幾分鐘(或幾秒)。同時,如果在某些分鐘內沒有完成處理,我想關閉該線程。 – Romeo

回答

5

退房一種叫做TaskCancellationToken。如果您決定(通過您喜歡的任何方式)它運行時間過長,您可以使用它來終止任務。

或者,您可以將其構建到ProcessRecords()方法本身中:只要讓它跟蹤自己的啓動時間並檢查流逝的時間,就可以讓seppuku運行時間過長;可能會更簡單。

這就是說,如果你還沒有給它一個鏡頭,你可能會檢查,看看是否.AsParallel()將在這裏爲您節省一些頭痛。有很多情況下,您可以完全將編譯器的並行性問題留給編譯器。

Parallel.ForEach(db.Records, r => ProcessRecord(r)); 

編輯:

Parallel.ForEach(db.Records, ProcessRecord); 

是。 :)

進一步編輯:

對於OP,不,TaskFactory不提供這樣的事情開箱。如果你想從流程之外終止流程,你需要使用某種觀察器線程來推出你自己的機制,以跟蹤你正在運行哪些任務,他們運行了多久以及他們各自的取消令牌(或者也許只是你在一個while循環頂部的布爾...)。

+1

只能用'ProcessRecord'替換'r => ProcessRecord(r)'嗎? – icktoofay

+0

謝謝你的建議。好的,Parallel.ForEach是要走的路。但是,我的問題依然如此。我怎麼知道沒有線程會繼續運行,消耗資源而沒有任何輸出? – Romeo