2013-10-29 29 views
15

當使用IProgress<T>報告進度,它應該是IProgress <T>多久報告進度

  • 代碼報告進展到它的進度報告限制是「合理」的頻率的責任, - 或 -
  • IProgress<T>的具體實施的責任是要知道,進展報告的頻率可能高於其展示此進展方式的合理頻率。

問題的背景是我有一些代碼,它使用IProgress<T>來報告進度,並以非常高的速度報告進度。我想用UI進度條顯示進度。如果我使用提供的Progress<T>實現(將進度發佈到UI SyncronizationContext),則會導致UI無響應(即,發送到消息隊列的消息太多,用戶甚至無法單擊「取消」對話框上的按鈕)。

所以,

  • 我可以報告更少解決這個問題,但如果我有一個IProgress<T>實現,只是寫了進步到一個日誌文件(並可以處理高報告頻率)。 - 或 -
  • 我可以通過創建我自己的特定IProgress<T>實現來解決此問題,該實現限制了我處理/報告進度的頻率。據推測,這個實現會記錄非UI線程的最新進度,然後(可能)UI將根據計時器進行更新。
+0

有趣的問題,但可能是題外話?我個人的觀點:消費者應該充分利用製片人的優點。所以沒有限制輸出+1。編輯:好的,如果製片人因爲性能原因限制自己,那麼這可能是一個很好的理由。 – igrimpe

+0

進度條通常取整數值0..100。如果你的更新沒有進入下一個整數,那麼沒有理由將其報告給用戶界面。但是我對專家的看法感興趣 – Harrison

+1

@哈里森,我認爲通常報告進展的方式對報告進度的代碼是有意義的。進度的消費者負責將其轉換成他們想要呈現的方式(例如完成的百分比)。 –

回答

11

寫一個裝飾器來調節通話。通過這種方式,您可以將調節邏輯和實際報告分開,您可以將其用於任何其他IProgress<T>實施。

當您想要限制進度報告時使用此裝飾器。用下面的類的實例簡單包裝你的進度報告者。

我已經把限制邏輯留給你了。您可以使其基於時間,基於通話量或其他標準。

public class ProgressThrottler<in T>: IProgress<T> { 
    public ProgressThrottler(IProgress<T> progress) { 
     if (progress == null) 
      throw new ArgumentNullException("progress"); 

     _progress = progress; 
    } 

    private readonly IProgress<T> _progress; 

    public void Report(T value) { 
     // Throttles the amount of calls 
     bool reportProgressAfterThrottling = ...; 

     if (reportProgressAfterThrottling) { 
      _progress.Report(value); 
     } 
    } 
} 
+0

這個想法是正確的,但是在實現中存在一個小錯誤。報告返回無效。另外,我沒有看到明確實現接口的意義,隱式實現至少可以做到這一點,恕我直言。 –

+0

我還在編輯中,但對於提示thanx。 – Maarten

+1

@KrisVandermotten明確實施在DI用戶中相當普遍,以防止直接與實現偶然耦合。 –