2009-09-13 33 views

Respuesta

315

En este artículo se ofrece una explicación bastante completa:

"Comparing the Timer Classes in the .NET Framework Class Library" - también disponible as a .chm file

La diferencia específica parece ser que System.Timers.Timer está orientada a las aplicaciones multitarea, y es por lo tanto seguro para subprocesos a través de su propiedad SynchronizationObject , mientras que System.Threading.Timer irónicamente no es seguro para hilos fuera de la caja.

No creo que haya una diferencia entre los dos en lo que respecta a cuán pequeños pueden ser sus intervalos.

+60

Creo que este extracto es esclarecedor: "A diferencia de System.Windows.Forms.Timer, la clase System.Timers.Timer, de forma predeterminada, llamará a su controlador de eventos del temporizador en un hilo de trabajo obtenido del tiempo de ejecución de lenguaje común (CLR) grupo de subprocesos [...] La clase System.Timers.Timer proporciona una manera fácil de lidiar con este dilema: expone una propiedad pública SynchronizingObject. Establecer esta propiedad en una instancia de Windows Form (o un control en un Windows Form) se asegurará de que el código en su controlador de eventos Elapsed se ejecute en el mismo hilo en el que SynchronizingObject fue instanciado. " – mico

+7

De acuerdo con la sección de seguridad de subprocesos de 'Threading.Timer' [artículo de MSDN] (http://msdn.microsoft.com/en-us/library/system.threading.timer%28v=vs.110%29. aspx), es perfectamente seguro para subprocesos ... – Pieter

+51

'System.Threading.Timer' es tan" irónicamente "no seguro para subprocesos como' System.Threading.Thread' y los subprocesos obtenidos a través del conjunto. El hecho de que estas clases no te detengan y administres el uso de la palabra clave 'lock' en sí no significa que estas clases no sean seguras en cuanto a los hilos. También podría decir 'System.Threading.Thread' no es seguro para los hilos, porque es exactamente igual de verdadero. –

110

En su libro "CLR a través de C#", Jeff Ritcher desalienta utilizando System.Timers.Timer, este temporizador se deriva de System.ComponentModel.Component, lo que le permite ser utilizado en la superficie de diseño de Visual Studio. De modo que solo sería útil si quiere un temporizador en una superficie de diseño.

Prefiere usar System.Threading.Timer para tareas en segundo plano en un subproceso de grupo de subprocesos.

+31

Se puede utilizar en una superficie de diseño; no significa que deba ser así, y no hay efectos perjudiciales por no hacerlo. Al leer el artículo en la respuesta anterior a esta pregunta, Timers.Timer parece mucho más preferible a Threading.Timer. –

+4

Bueno, lo que es preferible depende del contexto, ¿verdad? Según tengo entendido, System.Threading.Timer ejecuta la devolución de llamada pasada en una nueva cadena de trabajo desde ThreadPool. Lo que, supongo, es también por qué no es necesariamente seguro para subprocesos. Un poco tiene sentido. Entonces, en teoría, no tendrías que preocuparte por el arduo trabajo de hacer girar tu propio hilo de trabajo, ya que este cronómetro lo hará por ti. Un poco parece ridículamente útil. – Finster

+4

Usar 'System.Threading.Timer' es similar a usar un grupo de subprocesos o crear su propio subproceso. * De ** curso ** estas clases no manejan la sincronización por usted * - ¡ese es su trabajo! Ni un hilo de grupo de subprocesos, ni su propio subproceso, ni una devolución de llamada de temporizador manejarán el bloqueo: en qué objeto y de qué manera y en qué circunstancias debe bloquearse requiere buen juicio y la versión de subprocesamiento del temporizador le brinda la mayor flexibilidad y granularidad. –

127

System.Threading.Timer es un temporizador simple. Te devuelve la llamada a un hilo del grupo de subprocesos (del grupo de trabajadores).

System.Timers.Timer es un System.ComponentModel.Component que envuelve un System.Threading.Timer, y proporciona algunas características adicionales utilizadas para el envío en un hilo en particular.

System.Windows.Forms.Timer envuelve un nativo message-only-HWND y usa Window Timers para generar eventos en ese bucle de mensajes HWNDs.

Si su aplicación no tiene interfaz de usuario, y desea el temporizador .Net más ligero y de propósito general posible (porque está contento con su propio enhebrado/despacho) entonces System.Threading.Timer es tan bueno como lo consigue en el marco.

No estoy del todo seguro de lo que se supone que son los supuestos problemas con 'System.Threading.Timer'. Quizás es simplemente igual que pidió en esta pregunta: Thread-safety of System.Timers.Timer vs System.Threading.Timer, o tal vez todo el mundo sólo significa que:

  1. es fácil escribir las condiciones de carrera cuando se está utilizando temporizadores. P.ej. ver esta pregunta: Timer (System.Threading) thread safety

  2. reentrada de las notificaciones del temporizador, donde su evento de temporizador puede activar y volver a llamar al segundo tiempo antes de terminar de procesar la primera evento. P.ej.ver esta pregunta: Thread-safe execution using System.Threading.Timer and Monitor

20

me encontré con un corto de comparación MSDN

El .NET Framework Class Library incluye cuatro clases denominadas temporizador, cada uno de los cuales ofrece una funcionalidad diferente:

System.Timers.Timer , que dispara un evento y ejecuta el código en uno o más receptores de eventos a intervalos regulares. La clase está destinada al para su uso como componente de servicio o servidor en un entorno multiproceso ; no tiene interfaz de usuario y no es visible en tiempo de ejecución.

System.Threading.Timer, que ejecuta un único método de devolución de llamada en un hilo del grupo de subprocesos a intervalos regulares. El método de devolución de llamada es definido cuando se crea una instancia del temporizador y no se puede cambiar. Al igual que la clase System.Timers.Timer, esta clase está pensada para su uso como un componente de servicio o servidor en un entorno multiproceso; no tiene interfaz de usuario y no está visible en el tiempo de ejecución.

System.Windows.Forms.Timer, un componente de Windows Forms que dispara un evento y ejecuta el código en uno o más receptores de eventos a intervalos regulares de . El componente no tiene interfaz de usuario y está diseñado para el uso en un entorno de subproceso único.

System.Web.UI.Timer, un componente de ASP.NET que realiza devoluciones de páginas web asíncronas o síncronas a intervalos regulares.

1

Las dos clases son funcionalmente equivalentes, excepto que System.Timers.Timer tiene una opción para invocar todas sus devoluciones de llamada de expiración del temporizador a través ISynchronizeInvoke estableciendo SynchronizingObject. De lo contrario, ambos temporizadores invocarán devoluciones de llamada de vencimiento en los hilos del grupo de subprocesos.

Cuando arrastra un System.Timers.Timer en una superficie de diseño de Windows Forms, Visual Studio establece SynchronizingObject en el objeto de formulario, lo que provoca que se invoquen todas las devoluciones de vencimiento en el subproceso de la interfaz de usuario.

1

De MSDN: System.Threading.Timer es un temporizador simple y liviano que utiliza métodos de devolución de llamada y es servido por subprocesos de grupo de subprocesos. No se recomienda su uso con Windows Forms, porque sus devoluciones de llamada no se producen en el subproceso de la interfaz del usuario. System.Windows.Forms.Timer es una mejor opción para usar con Windows Forms. Para la funcionalidad del temporizador basado en el servidor, puede considerar usar System.Timers.Timer, que genera eventos y tiene funciones adicionales.

Source

15

Una diferencia importante no citados anteriormente que podría atrapar a salir es que System.Timers.Timer traga silencio excepciones, mientras que System.Threading.Timer no.

Por ejemplo:

var timer = new System.Timers.Timer { AutoReset = false }; 
timer.Elapsed += (sender, args) => 
{ 
    var z = 0; 
    var i = 1/z; 
}; 
timer.Start(); 

vs

var timer = new System.Threading.Timer(x => 
{ 
    var z = 0; 
    var i = 1/z; 
}, null, 0, Timeout.Infinite); 
+0

Hace poco llegué a este problema con Timers.Timer y ha sido muy doloroso ... Alguna idea de cómo Podría reescribir con Threading.Timer? http://stackoverflow.com/questions/41618324/windows-service-runs-but-stops-processing-after-two-days –

23

System.Timers.Timer parece estar en desuso con .NET y ASP.NET Core Core. Intenta usar System.Threading.Timer en futuras aplicaciones.


EDIT: OK, quiero ser más preciso:

Con el nuevo Marco de base de .NET, Microsoft suspendió algunas tecnologías de .NET Framework. Para entender eso: .NET Core es un marco totalmente nuevo - reescrito, multiplataforma, etc. No quiero profundizar aquí en detalle - por favor, lea el .NET Blog.

En el blog es un buen artículo abundando portar a .NET Core que explica también las dificultades que puede golpear. Una parte de esto es usar el .NET Portability Analyzer Visual Studio Add-In y corregir los errores que recibe.

Para la clase System.Timers.Timer, dijo, que .NET Framework, se admite versión = v4.6.2, pero .NET Core, Version = v5.0 y .NETPlatform, versión = v5.0 no lo es. Cambios recomendados: Use System.Threading.Timer.

Así que eso me parece que System.Timers.Timer se ha ido para .NET Core.

P.S .: Pero podría volver: Microsoft anunció que desea realizar algunos cambios en CoreCLR (el nombre del marco que utiliza para .NET Core) para facilitar el esfuerzo de portabilidad.

+1

Parece que es cierto: https://github.com/npgsql/npgsql/issues/471 # issuecomment-94104090 –

+0

@Taegost, su uso también es limitado: consulte MSDN https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx y lea el comentarios sobre la disponibilidad de la plataforma. – astrowalker

+0

@astrowalker - Gracias por eso, en el momento en que hice el comentario esta respuesta casi no tenía detalles. Como ahora tiene el detalle por el que estaba preguntando, eliminé mi comentario. – Taegost

Cuestiones relacionadas