Todas, aquí hay una pregunta sobre el diseño/las mejores prácticas de un caso complejo de cancelación Tarea: s en C#. ¿Cómo se implementa la cancelación de una tarea compartida?Cómo implementar la cancelación de tareas compartidas: s en C#
Como un ejemplo mínimo, supongamos lo siguiente; tenemos una operación de larga duración, cooperativamente cancelable 'Trabajo'. Acepta un token de cancelación como argumento y tira si se ha cancelado. Funciona en algún estado de aplicación y devuelve un valor. Su resultado es requerido independientemente por dos componentes UI.
Si bien el estado de la aplicación no se modifica, el valor de la función Work debe almacenarse en caché, y si un cálculo está en curso, una nueva solicitud no debe iniciar un segundo cálculo sino comenzar a esperar un resultado.
Cualquiera de los componentes de la interfaz de usuario debería poder cancelar su tarea sin afectar la otra tarea de los componentes de la interfaz de usuario.
¿Estás conmigo hasta ahora?
Lo anterior se puede lograr mediante la introducción de un caché de tareas que envuelve la tarea de trabajo real en TaskCompletionSources, cuya tarea: s se devuelve a los componentes de la interfaz de usuario. Si un componente de la interfaz de usuario cancela su tarea, solo abandona la tarea TaskCompletionSource y no la tarea subyacente. Esto está todo bien. Los componentes de UI crean CanceSource y la solicitud para cancelar es un diseño descendente normal, con TaskCompletionSource Tarea que coopera en la parte inferior.
Ahora, al problema real. ¿Qué hacer cuando cambia el estado de la aplicación? Supongamos que hacer funcionar la función 'Trabajo' en una copia del estado no es factible.
Una solución sería escuchar el cambio de estado en la memoria caché de la tarea (o de allí). Si el caché tiene un CancelToken utilizado por la tarea subyacente, el que ejecuta la función Work, podría cancelarlo. Esto podría desencadenar una cancelación de todas las TaskCompletionSources Task: s adjuntas, y así ambos componentes de la interfaz de usuario obtendrían tareas canceladas. Este es un tipo de cancelación de abajo hacia arriba.
¿Existe alguna forma de hacerlo? ¿Hay un patrón de diseño que lo describa en algún lugar?
Se puede implementar la cancelación de abajo hacia arriba, pero se siente un poco raro. La tarea de UI se crea con un CancellationToken, pero se cancela debido a otro CancellationToken (interno). Además, dado que los tokens no son lo mismo, OperationCancelledException no puede ignorarse en la IU, lo que (eventualmente) llevaría a que se genere una excepción en el finalizador de la Tarea externa.
excelente pregunta, aunque mi primera reacción fue "tl; dr" – dtb
Por lo tanto, para aclarar; tiene dos consumidores del resultado de la tarea y solo desea que una tarea calcule el valor por estado de la aplicación; sin embargo, ¿desea que cada consumidor pueda "cancelar" la espera del resultado de la tarea? – Tejs
sí, pero también que un cambio de estado debe cancelar el cálculo. – 4ZM