2011-01-19 37 views
0

我有一個應用程序,我使用Paraller.ForEach()循環下載和處理大約7,800個URL。使用這種技術可以讓我的計算機在大約4.5分鐘內完成這項操作(平均用時將近28分鐘)。Parallel.ForEach()....如何最好地從外部終止循環?

由於這是一個WinForms應用我允許用戶通過簡單地點擊停止按鈕,這將反過來設置的易失性布爾變量爲「假」早「停止」過程中運行。在我的Parallel.ForEach()循環的頂部,我檢查該變量的狀態,如果它已被設置爲'false',我只需調用ParallelLoopState.Stop()方法。如果ParallelLoopState尚未停止,我的下一個代碼塊將在循環內運行。

的偉大工程。使用這個實現已經經歷了三個星期,我一直在使用它。

但是我只是在閱讀並遇到「CancellationTokenSource」和「CancellationToken」類,並發現它們被設計爲基本上執行相同的操作......以允許在外部取消並行循環。

誰能告訴我,如果他們預見到問題,我繼續用我現有的實現?

Parallel.ForEach(searchList, (url, state) => 
{ 
    if (!this.isSearching) 
    { 
     state.Stop(); 

     OnSearchEvent(new SearchStatusEventArgs(SearchState.STOP_REQUESTED, ......)); 
    } 

    if (!state.IsStopped) 
    { 
     // continue on with regular processing ....... 
    } 
}); 
+2

相信YAGNI(你是不是要去需要它)原則上可以向上轉型爲「如果沒壞,就不要修理它」 :) – 2011-01-19 16:01:40

+0

我與你戴夫。由於我是使用並行擴展的新手,我只是想確保我沒有構建某些隱藏的gremlins,但我還沒有意識到隱藏的某些地方。沒有什麼比建立一座你認爲值得信賴的橋更糟糕,只是意識到你站在地雷上。 – BonanzaDriver 2011-01-19 16:27:53

回答

2

看起來不錯! CancellationTokenSource和CancellationToken確實適用於Tasks,尤其是在任務通過ContinueWith連接在一起的情況下。從那裏,你可以詢問令牌(線程安全),並拋出異常或退出線程完全相同的方式你已經這樣做了。

除非你去了複雜的任務鏈和封閉的路線,然後我會說沒有必要使事情變得複雜!