Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

466
Vistas
¿Cancelar task.delay sin excepción o usar una excepción para controlar el flujo?

No estoy seguro acerca de dos posibilidades para reaccionar a un evento en mi código. Sobre todo me preocupa cuál necesita menos recursos. Tengo un método con un observador registrado en un productor de eventproducer . Si el productor de eventproducer devuelve algo, el método sale y la persona que llama al método inicia el método nuevamente (puede pensar en ello como una especie de sondeo largo).

El productor de eventproducer a veces dispara muchos eventos por segundo y a veces descansa durante minutos.

El primer enfoque fue esperar un retraso de 500 ms y luego verificar si hay algo que devolver o, de lo contrario (hasta un tiempo de espera de 5 minutos), volver a retrasar 500 ms.

 eventProducer.RegisterListener((events)=>{evList.Add(events)}); while(evList.Count=0 && !TimeOut){ await Task.Delay(500);} eventProducer.UnRegister(...); // return evList, method gets recalled immediately

El segundo enfoque fue usar un CancellationToken . Si el eventproducer produce algo, CancellationTokenSource cancela la fuente. Y en el método espero Task.Delay(5min, cancellationToken) .

 eventProducer.RegisterListener((events)=>{evList.Add(events); cancelSource.Cancel();} try { await Task.Delay(5min, cancellationToken) } catch(TaskCanceledException){//nothing to do}; eventProducer.UnRegister(...); // return evList, method gets recalled immediately

Las ventajas del segundo enfoque son que el método regresa inmediatamente si el productor produce algo y que no tenemos que esperar y despertarnos en un bucle.

Pero con el segundo enfoque, cada vez que el productor produce algo, se lanza una TaskCanceledException . Me preocupa que esto pueda afectar la carga del sistema más que la activación y la espera cada 500 ms, especialmente en los momentos en que el productor de eventproducer produce muchos eventos.

¿Estoy sobreestimando el costo de lanzar y capturar una excepción? ¿Y hay alguna manera de cancelar Task.Delay con un CancellationToken pero sin lanzar una TaskCanceledException ? IE algo como task.setComplete ?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Si desea una notificación inmediata similar a la que le brinda una cancelación pero sin excepción, simplemente puede usar TaskCompletionSource .

TaskCompletionSource es cómo crea una tarea de promesa. Obtiene una tarea incompleta de la propiedad Task y la completa (o cancela) con SetResult . Puede usarlo para transmitir el resultado en sí:

 var tcs = new TaskCompletionSource<Events>(); eventProducer.RegisterListener(events => tcs.SetResult(events)); var result = await tcs.Task; eventProducer.UnRegister(...);

Esta solución no tiene excepciones y no utiliza sondeos innecesarios.


Para responder a sus preguntas específicas:

¿Estoy sobreestimando el costo de lanzar y capturar una excepción?

Probablemente. Necesita probar y demostrar que es realmente un problema.

¿Y hay alguna manera de cancelar Task.Delay con un CancellationToken pero sin lanzar una TaskCanceledException ?

Sí. Agregue una continuación vacía:

 var delayTask = Task.Delay(1000, cancellationToken); var continuationTask = delayTask.ContinueWith(task => { }); await continuationTask;
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda