2012-09-27 41 views
1

我有一個背景異步任務,從點擊按鈕觸發。我有一個IsBusy屬性,該屬性在任務啓動時和在finally塊內進行更新,以解釋或完成。非即時任務取消,重新啓動和繁忙指標

當前我的按鈕單擊事件取消上一個任務,並在重新單擊時啓動新的任務;但是由於第一個任務的取消可能會滯後於新任務的開始,所以布爾型IsBusy指標可能會失去同步。

我的問題是如何處理這種情況。

我目前的解決方案是不直接更新布爾值,而是使用在開始和完成時遞增/遞減的整數 - IsBusy屬性返回BusyCount > 0。然而,這需要添加線程安全性,並不覺得是一個好的解決方案。

另一個想法是在任務被解僱時存儲任務,並且只作爲第一個任務的延續開始新任務。這解釋了取消問題,但是強制給調用者而不是任務造成不必要的延遲(不管分數)還是'合同'。

我最後的想法是創建一個像BusyTokenSource類的東西,它提供一次性的BusyTokens,它可以從一個線程安全的集合中被添加/刪除..但是這看起來像是矯枉過正。

有沒有更好的/適當的/常用的方法來處理這種類型的情況?

編輯:

我結束了上面我最後一個念頭去,並寫下了「BusyToken」類。通過這種方式,我可以簡單地將功能包裝在using(BusyTokenSource.GetToken()){}中,讓內部收集和Dispose負責計數和繁忙狀態。

回答

2

我想你應該每個任務都有一個繁忙狀態。不知道你的BusyTokenSource想法如何工作,但聽起來有點像。

創建一個holder類:

class BusyStatus { bool IsBusy; } 

並給它一個新的實例每次啓動任務。當您不再對舊任務感興趣時,只需放棄舊的BusyStatus並創建一個新實例。舊的任務最終會完成並設置忙碌狀態,但在舊的實例上再也無人使用了。

只要確保舊任務不會意外引用新的BusyStatus實例。

作爲更一般的規則,讓每個Task(或Thread)在不同的數據結構上工作通常很有用。這是一個有用的總體指導原則。它使您獲得簡單性,並可以輕鬆實現安全。

+0

感謝您的回覆。有了上面的建議,如何「聚合」所有者的整體繁忙狀態(在我的案例中是視圖模型)? –

+0

@ach,你可以把「放棄」的任務視爲不忙嗎?可能是有道理的,因爲結果將被丟棄。如果不是,您可能需要一個同步變量(int),用於存儲繁忙任務的數量。我看不到一個方法。 – usr

+0

感謝您的回覆。我在上面添加了一個編輯,我使用一次性BusyToken方法。它效果很好。 –