2013-05-10 17 views
1
分離結果計算

我們正在考慮分開這些成果的承諾計算一些成果工作的API模式是:使用任務,以此來犯結果

interface IResults { } 
    class Results : IResults { } 

    Task<IResults> CalculateResultsAsync(CancellationToken ct) 
    { 
     return Task.Run<IResults>(() => new Results(), ct); 
    } 

    void CommitResults(IResults iresults) 
    { 
     Results results = (Results)iresults; 
     // Commit the results 
    } 

這將允許客戶端有一個用戶界面,可以計算出某些結果,並知道計算何時準備就緒,然後在那個時候決定是否提交結果。這主要是爲了幫助我們處理在計算過程中,UI將允許用戶取消操作的情況。我們要確保:雖然動作還是撤銷

  • 取消UI時,纔會顯示(即一旦我們在CommitResults,有沒有回頭路),所以一旦CalculateResultsAsync任務完成後,我們採取了取消用戶界面,只要用戶沒有取消,繼續並調用提交方法。
  • 我們不希望有一個用戶點擊取消並且結果無論如何都被提交的情況(即競態條件)。
  • 客戶永遠不會使用IResults而不是將其傳遞迴CommitResults

問: 一般的問題是:這是一個好的方法嗎?具體做法是:

  1. 這感覺不對具有這種分成兩種方法,因爲客戶端是永遠不會檢查IResults,他們只是遞迴Commit方法。
  2. 有沒有一個標準的方法來解決這個問題?

回答

3

這是一個非常標準模式(如果不是理想的模式),尤其是當你的結果對象是不可變。我們通常在使用TPL的Visual Studio代碼庫中的代碼中執行此操作。當你的異步/並行邏輯正在處理數據時,總是存在許多快樂,而變異的廢話則遠離它。

如果您熟悉或聽說過「Roslyn」項目,這是一種我們實際上鼓勵人們使用的模式。這個想法是重構可以在後臺異步處理,併產生一個對象,就像你的結果一樣,它表示重構的結果。然後,在UI線程上,任何人都可以使用其中一個結果對象並應用它,它將更新所有文件以包含新文本。

我確實覺得整個IResults /結果件事有點奇怪 - 它,如果你使用這個隱藏自己或無法實現目前尚不清楚。如果空接口和轉換錯誤,你可以考慮向IResult添加一個提交方法,結果對象實現該方法。由你決定。

+0

我們結束了其具有Commit方法的IResult去(如你所說):這種方式有沒有需要有兩個方法來表示一個動作。 – 2013-05-29 18:59:14

0

我不確定爲什麼你需要這種模式。對我來說,如果你在開始提交之前檢查CancellationToken,你會得到完全相同的結果,並且接口更簡單。

+0

然後用戶界面如何知道何時關閉顯示取消按鈕的UI(因爲如果用戶無法取消操作,我不希望用戶能夠單擊取消按鈕)。 – 2013-05-11 01:04:30

+0

馬特正在做的一個優點是沒有給予提交方法取消令牌,他們不能搞砸,認爲他們必須支持取消。 Roslyn在內部有幾個地方,我們的方法有一個很大的「不檢查這個點之後的取消令牌」的評論,這絕對是不雅觀的。另外,如果提交具有UI線程關聯性,則將其進一步分解是一個很好的模式。 – 2013-05-11 01:48:56