20

IProgress<T>進捗状況を報告するために使用する場合、

  • 進行状況を報告するコードの責任は、その進行状況報告を「妥当な」頻度に制限する、または
  • IProgress<T>進捗状況の報告が、この進捗状況を提示する方法として妥当な頻度よりも高い頻度で行われる可能性があることに注意することは、特定の実装の責任です。

IProgress<T>質問の文脈は、進行状況を報告するために使用するコードがいくつかあり、進行状況を非常に高い速度で報告することです。UIプログレスバーで進行状況を表示したい。提供されたProgress<T>実装 (進行状況を UI SyncronizationContext にポストする) を使用すると、UI が応答しなくなります (つまり、メッセージ キューに送信されるメッセージが多すぎるため、ユーザーは [キャンセル] ボタンをクリックすることさえできません)。ダイアログで)。

そう、

  • 報告を減らすことでこれを修正できますが、進行状況をログ ファイルに書き込むだけの実装があったとしたらどうでしょうIProgress<T>(そして、高い報告頻度を処理できます)。-また-
  • IProgress<T>進行状況を処理/報告する頻度を制限する独自の特定の実装を作成することで、これを修正できました。おそらく、この実装は非 UI スレッドで最新の進行状況を記録し、(おそらく) タイマーに基づいて UI を更新します。
4

2 に答える 2

17

呼び出しを調整するデコレータを書きます。IProgress<T>このようにして、スロットリングのロジックと実際のレポートを分離し、他の実装に使用できます。

進行状況のレポートを抑制したい場合は、このデコレーターを使用してください。以下のクラスのインスタンスで進捗レポートを簡単にラップします。

スロットリングのロジックはあなたに任せました。時間ベース、通話量ベース、またはその他の基準にすることができます。

public class ProgressThrottler<T>: IProgress<T> {
    public ProgressThrottler(IProgress<T> progress) {
        _progress = progress ?? throw new ArgumentNullException("progress");
    }

    private readonly IProgress<T> _progress;

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

        if (reportProgressAfterThrottling) {
            _progress.Report(value);
        }
    }
}
于 2013-10-29T14:43:06.827 に答える