2011-02-07 12 views
6

Tengo una pregunta sobre qué mecanismo para cancelar una operación asincrónica en curso podría ser utilizado, en lugar de un token de cancelación en el contexto async/await. Estoy seguro de que esta es una decisión de diseño bien estudiada que toma en cuenta la naturaleza imperativa del lenguaje, pero en situaciones reales tener que pasar un objeto de cancelación a todos sus métodos asíncronos es, al menos, un poco doloroso. Hay otras ideas de diseño de la comunidad C#, o el mecanismo de cancelación propuesto está bien? Creo que me estoy perdiendo algo.async/aguardar mecanismo de cancelación

+0

El mecanismo de cancelación que utiliza un token de cancelación parece ser la dirección en la que se orientan las cosas, incluso en C# 5 CTP en Async. http://msdn.microsoft.com/en-us/vstudio/gg316360. No es llamar a C# 5, pero lo estoy usando aquí para indicar la "próxima" versión de C#. –

+0

Acaba de darse cuenta de que ha usado "esperar" en su pregunta para que esté familiarizado con el CTP. Creo que la Biblioteca de Tareas paralelas (.NET 4) confirmó que las instalaciones que proporcionaba eran el camino a seguir, por lo que el CTP Async usa el mismo paradigma. –

+0

Relacionados: http://stackoverflow.com/q/4914374/60761 –

Respuesta

4

El token de cancelación es la mejor práctica, especialmente cuando el proceso asíncrono es costoso, no tiene una condición de finalización preestablecida o involucra recursos externos.

Sin embargo, puede, si lo desea, simplemente "darse por vencido". En lugar de decirle al subproceso asincrónico que interrumpa el procesamiento y la limpieza, simplemente "agote el tiempo"; deja de esperar que se complete, separe a los oyentes y siga funcionando. Cuando el hilo finalmente se complete, comprobará su evento, se dará cuenta de que nadie está escuchando y terminará silenciosamente. La ventaja es la simplicidad, sin embargo, hay muchas situaciones en las que esto sería una mala cosa:

  • Si el proceso asíncrono mantendrá procesamiento siempre a menos que usted le diga que pare, que se mantendrá funcionando en segundo plano, atando hasta la CPU y otros recursos, hasta que se cierre la aplicación, momento en el que se eliminará el hilo.
  • Si el subproceso asincrónico realiza una unidad de trabajo anulable y reversible, como una operación de base de datos, si el usuario presiona cancelar, espera que todo lo hecho hasta ahora se haya retrotraído. Si deja de escuchar y continúa, lo que obtendrán es que lo que pensaron que cancelaron se realizó.
  • En la mayoría de los casos, las operaciones asincrónicas implican recursos externos que requieren tiempo para trabajar y también requieren una limpieza adecuada. Los enchufes de red deben estar desconectados, las conexiones DB cerradas, los archivos desbloqueados, etc. Aunque darse por vencido significa que no tiene que lidiar con eso, en lugar de dejar que el hilo termine normalmente, una experiencia de usuario común es que el usuario se canse, golpee cancelar y luego volver a intentar la operación. Eso significa que el recurso que utilizó en la operación asincrónica anterior tiene que ser liberado para usarlo nuevamente.
1

Para que la cancelación de una operación asíncrona tenga sentido, esa operación debe realizar pasos discretos, ya que está en funcionamiento verificar el token de cancelación y evitar que continúe. Es decir. el token de cancelación es simplemente un patrón a implementar, no un mecanismo de async/await.

Lo que significa que si su operación asíncrona es solo una llamada de E/S con un controlador de finalización, también puede darse por vencido en lugar de cancelar, ya que la operación no tendrá la oportunidad de verificar su token hasta esa llamada regresa y en ese punto no hay nada que ganar.

Por lo tanto, al considerar un token de cancelación, primero considere si esta operación se puede hacer más eficiente apoyando la cancelación o si simplemente no esperar a que finalice (es decir, utilizar un mecanismo de tiempo de espera) tiene más sentido.