2011-12-01 67 views
2

我正在開發一個實現協議棧的類庫。在那裏我有一個實現IAsyncResult的異步操作DoSomething。此方法的用戶可以使用BeginDoSomething和EndDoSomething。只要這是一個很普遍的任務。取消異步操作

現在我得到了使異步操作中止的要求。我能想到的幾種方法來實現這一點,但我不知道哪一個是最好的:

  1. 有除了BeginDoSomething和EndDoSomething一個CancelDoSomething方法。這不是常見的asaync模式,因此不容易找到操作的用戶。
  2. 根據沒有。 1:有取消屬性
  3. 由BeginDoSomething返回的IAsyncResult實例可以被轉換爲DoSomethingAsyncResult。 DoSomethingAsyncResult有一個Cancel方法。再一次,這不是異步模式的常見用法,也很難知道類庫的「普通用戶」。
  4. 根據沒有。 3:有取消屬性
  5. BeginDoSomething返回的IAsyncResult實例實現IAbortableAsyncResult:public IAbortableAsyncResult:IAsyncResult { void Abort(); }。對我來說,這似乎是最優雅的方式。當用戶使用BeginDoSomething開始操作時,他會得到一個IAbortableAsyncResult的實例,這意味着這個特殊功能會突出地介紹給他。

什麼是最佳解決方案?有更多的方法可以解決這個問題嗎?我更喜歡不。 5,因爲它沒有代碼味道(至少我現在還沒有認出)。

[編輯]

不依賴於TPL/.NET 4的一種方法被理解爲具有一個解決方案,也適用於不能被移植到.NET架構中的最新版本的舊代碼。

[/編輯]

回答

3

加入的CancellationToken和CancellationTokenSource在4.0到.NET,並從此形成用於共同消除圖案的基礎。一般來說,異步方法有一個需要CancellationToken的重載。

CancellationTokens的使用者可以在令牌被取消時註冊回調,並使用回調來停止執行。或者,如果任務不是特別長時間執行,則可以間歇性地查詢IsCanceled屬性。

CancellationToken是異步任務使用的接口,任務的發起者使用CancellationTokenSource發出此令牌,並可能在將來取消它。

這種方法的好處之一,除了它成爲一種解決方法的標準方法之外,它是可組合的。如果任務組合了其他幾個可取消的異步操作,則可以將相同的取消令牌傳遞給它們,並且取消應該自動生效。

+0

感謝您的回答。我知道TPL,它是取消功能。對不起,我沒有提到這個問題。我更多地尋找一種解決方案,它不會使用.NET 4功能,但更適用於傳統代碼。 – PVitt

+0

當我在TPL中看到它時,我非常喜歡這種模式,所以當我不得不在緊湊框架中編寫類似的代碼時,我只是將模式移植到了其中。儘管TPL中的實施經過了高度優化,但您沒有理由不能在傳統設置中推出自己的版本以達到相同的目的。 –

+0

嗯,好主意。還沒有想到它。 – PVitt