IProgress <T>报告进度的频率

Mat*_*ith 16 c# progress async-await

IProgress<T>用于报告进度时,它应该是

  • 代码报告进度的责任是将进度报告限制在"合理"的频率, - 或 -
  • 具体实施的责任是IProgress<T>要意识到进展报告的频率可能高于其提出这一进展的方式.

问题的背景是我有一些IProgress<T>用于报告进度的代码,它以非常高的速度报告进展情况.我想用UI进度条显示进度.如果我使用提供的Progress<T>实现(将进度发布到UI SyncronizationContext),那么它会导致UI无响应(即,有很多消息发送到消息队列,用户甚至无法单击"取消"按钮在对话框上).

所以,

  • 我可以通过报告更少来解决这个问题,但如果我的IProgress<T>实现只是将进度写入日志文件(并且可以处理高报告频率),那该怎么办呢?-要么-
  • 我可以通过创建自己的特定IProgress<T>实现来解决这个问题,该实现限制了我处理/报告进度的频率.据推测,此实现将记录非UI线程的最新进度,然后(可能)UI将基于计时器进行更新.

Maa*_*ten 13

写一个限制调用的装饰器.通过这种方式,您可以将限制逻辑与实际报告分开,并将其用于任何其他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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @KrisVandermotten 显式实现在 DI 用户中相当常见,以阻止意外直接耦合到实现。 (2认同)