2009-03-18 17 views
20

Si estoy usando EventWaitHandle (o AutoResetEvent, ManualResetEvent) para sincronizar entre subprocesos, entonces ¿necesito llamar a los métodos Close() o Dispose() en ese identificador de evento cuando haya terminado con ellos?¿Debo eliminar() o Cerrar() un EventWaitHandle?

EventWaitHandle hereda de WaitHandle, que implementa IDisposable. Y FxCop se queja si no implemento IDisposable en cualquier clase que contenga un EventWaitHandle. Entonces esto sugiere que necesito llamarlo.

Sin embargo, ninguno de estos ejemplos de uso de MSDN llaman Dispose() o Close():

http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(VS.80).aspx

Se trata sólo de un ejemplo de Microsoft ignorando su propio consejo?

Respuesta

20

El recurso desechable de EventWaitHandle es en realidad un SafeHandle (envuelto en un SafeWaitHandle). SafeHandle implementa un finalizador, que finalmente se asegura de que se libere el recurso necesario, por lo que debe ser seguro dejar que el recolector de basura/finalizador lo maneje en este caso.

Sin embargo, siempre es una buena idea llamar explícitamente al Dispose() cuando el recurso ya no se necesita.

El capítulo con hilo en C# 3.0 in a Nutshell estados

Esta práctica es (posiblemente) aceptable con wait maneja porque tienen una carga OS luz (asíncronos delegados se basan en exactamente este mecanismo para lanzar su IAsyncResult ' s espera manejar).

+0

Argumentaría que dejar que el GC lo recoja es bastante indeseable. Dejar el trabajo al finalizador es solo una mala práctica. Solo hay un finalizador único y hacer que haga más de lo que debería no es bueno. Si el hilo se bloquea, tu aplicación se cuelga. Si se lanza una excepción en el hilo del finalizador, su AppDomain se bloquea. Tener el patrón de disposición adecuado garantiza que se llame a GC.SuppressFinalize(), lo que suprime la finalización de este objeto. Tengo un ejemplo de implementar IDisposable - http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html –

+0

Estoy de acuerdo y es por eso que declaro que debe llamar explícitamente a 'Dispose '. –

6

Debe deshacerse de ellos explícitamente. Close() es más apropiado para ellos ya que llama a Dispose().

2

Las definiciones de clases de MSDN:

public class EventWaitHandle : WaitHandle 
public abstract class WaitHandle : MarshalByRefObject, IDisposable 

Así que sí que deben como WaitHandle es IDisposable. FxCop encontraría esto como una violación de las reglas si no lo hiciera.

+0

Gracias Peter, pero ¿por qué los ejemplos de uso de MSDN no se llaman Close() o Dispose()? ¿Es esto solo que Microsoft no sigue sus propios consejos? – GrahamS

+1

Supongo que es 50% que no sigue sus propios consejos, y 50% trata de mantener los ejemplos lo más breves posible ... con un acompañamiento de la gente que escribe los ejemplos (no los desarrolladores sdk centrales) sin saberlo. –

Cuestiones relacionadas