2011-06-15 18 views
6

He notado una nueva tendencia en .NET 4.0, específicamente en escenarios potencialmente multiproceso, que es evitar eventos y proporcionar métodos de suscriptor.Método de suscriptor vs evento

Por ejemplo, System.Threading.Tasks.Task y Task<TResult> tienen ContinueWith() métodos en lugar de un evento Completado o Finalizado. Otro ejemplo es System.Threading.CancellationToken: tiene un método Register() en lugar de un evento CancellationRequested.

Mientras Task.ContinueWith() es lógico, ya que permite una fácil encadenamiento de tareas (no sería tan elegante, con eventos), y que también permite Task<TResult> heredar de Task (porque de esta manera, puede proporcionar Task<TResult> sobrecargas apropiadas, que no sería posible para un evento: si tiene un evento EventHandler Finalizado en Tarea, todo lo que puede hacer es crear otro evento, decir, evento terminado en Task<TResult>, que no es muy bueno), pero no puedo encontrar el misma explicación para CancellationToken.Register().

Entonces, ¿cuáles son las desventajas de los eventos en escenarios similares? ¿Debo seguir también este patrón? Para aclarar, ¿cuál de los siguientes debería elegir? ¿Cuándo debería preferir uno contra el otro?

public event EventHandler Finished; 

// or 

public IDisposable OnFinished(Action continuation) 

Muchas gracias!

+0

@Jon Skeet: gracias, no me di cuenta de que mis corchetes ángel necesitaban escapar. – ShdNx

+0

Los eventos de interfaz de usuario, etc. se pueden publicar utilizando la cola de mensajes de la interfaz de usuario y pueden ser realmente lentos/pesados ​​en comparación con el uso de un delegado o una tarea simple. – CodingBarfield

+0

@Barfieldmv: La llamada de acción podría publicarse utilizando la misma técnica con Invoke/BeginInvoke al Hilo de interfaz de usuario. No es la diferencia. –

Respuesta

2

Supongo que una ventaja del uso de métodos de suscriptor es que tiene la capacidad de especificar fácilmente el hilo en el que se ejecutará su delegado. Ver this overload de CancellationToken.Register().

Upd: Bueno, en realidad puede especificar el contexto de sincronización en el que se publicará su delegado.

Tienes razón sobre la tendencia. This article en MSDN Magazine afirma lo siguiente:

Los nuevos componentes no deben utilizar el modelo asincrónico basado en eventos . El Visual Studio Comunidad asíncrono Technology Preview (CTP) incluye un documento que describe el modelo asincrónico basado en tareas, en las que componentes vuelven finalidad y objetos de tareas en lugar de eventos de recaudación a través SynchronizationContext. Las basadas en tareas son el futuro de la programación asincrónica en .NET.

Y el document el artículo se refiere a dice

iniciación y terminación de un funcionamiento asíncrono en el TAP son representado por un único método, y por lo tanto no es sólo un método de nombre. Esto es en contraste con el patrón IAsyncResult, o el patrón de APM, donde se requieren BeginMethodName y métodos EndMethodName, y en contraste con la patrón basado en eventos asíncrona, o EAP, donde se requiere un MethodNameAsync en Además a uno o más eventos, evento tipos de delegados controladores, y tipos derivados de EventArg.

Y de hecho, ocuparse de una cosa en lugar de muchas es algo bueno. Pero esto es más una ventaja de TAP sobre EAP, no la ventaja de los métodos de suscriptor.

+0

Eso tiene sentido. Los métodos (métodos de suscriptor) son más flexibles que los eventos y también son menos problemáticos (por ejemplo, pérdidas de memoria relacionadas con eventos). Por otro lado, los métodos se sienten como un paso atrás, porque el programador también tiene que implementar una lista que almacena las devoluciones de llamada, y se preocupa por la seguridad de las secuencias de la lista de devolución de llamada. Por lo tanto, parece que, en general, los eventos son aún preferibles sobre los métodos simples de suscriptor (no se habla de EAP aquí), y los métodos de los suscriptores generalmente no valen la pena (excepto cuando se especifica un comportamiento de devolución de llamada especial, por ejemplo). ¡Gracias por la respuesta! – ShdNx

Cuestiones relacionadas