c# - tareas - no se puede usar await en void
IProgress<T> con qué frecuencia informar el progreso (1)
Al usar IProgress<T>
para informar el progreso, ¿debería ser
- la responsabilidad del código que informa el progreso de limitar sus informes de progreso a una frecuencia que es "razonable", o bien
- la responsabilidad de la implementación específica de
IProgress<T>
a tener en cuenta que el informe del progreso puede tener una frecuencia más alta que la razonable por la forma en que presentará este progreso.
El contexto de la pregunta es que tengo un código que usa IProgress<T>
para informar el progreso, e informa el progreso a una tasa muy alta. Quiero mostrar el progreso con una barra de progreso de UI. Si utilizo la implementación Progress<T>
(que publica el progreso en el UI SyncronizationContext), la interfaz de usuario deja de responder (es decir, se envían tantos mensajes a la cola de mensajes que el usuario ni siquiera puede hacer clic en Botón "Cancelar" en el cuadro de diálogo).
Asi que,
- Podría solucionar esto informando menos, pero ¿qué
IProgress<T>
si tengo unaIProgress<T>
que acaba de escribir el progreso en un archivo de registro (y podría manejar la alta frecuencia de informes). -o- - Podría solucionarlo creando mi propia
IProgress<T>
específica deIProgress<T>
que limita la frecuencia con la queIProgress<T>
/ informé el progreso. Presumiblemente, esta implementación registraría el progreso más reciente en un hilo no relacionado con la interfaz de usuario, y luego (tal vez) la interfaz de usuario se actualizaría en función de un temporizador.
Escribe un decorador que acelera las llamadas. De esta forma se separa la lógica de regulación y los informes reales, y se puede usar para cualquier otra IProgress<T>
.
Use este decorador cuando desee acelerar el informe de progreso. Envuelva su informe de progreso con la instancia de la clase a continuación.
Te dejé la lógica de la aceleración. Puede hacerlo basado en el tiempo, basado en la cantidad de llamadas o en otros criterios.
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);
}
}
}