servicio de windows vs tarea programada

115

¿Cuáles son los pros y los contras de los servicios de Windows frente a las tareas programadas para ejecutar un programa repetidamente (por ejemplo, cada dos minutos)?

Manu
fuente

Respuestas:

51

Actualizar:

Casi cuatro años después de mi respuesta original y esta respuesta está muy desactualizada. Desde TopShelf apareció , el desarrollo de los servicios de Windows se volvió fácil. Ahora solo necesita descubrir cómo admitir la conmutación por error ...

Respuesta original:

Realmente no soy fanático del Programador de Windows. La contraseña del usuario debe proporcionarse como @moodforall señala arriba, lo cual es divertido cuando alguien cambia la contraseña de ese usuario.

La otra gran molestia con el Programador de Windows es que se ejecuta de forma interactiva y no como un proceso en segundo plano. Cuando aparezcan 15 ventanas de MS-DOS cada 20 minutos durante una sesión de RDP, se echará a perder por no haberlas instalado como servicios de Windows.

Independientemente de lo que elija, ciertamente le recomiendo que separe su código de procesamiento en un componente diferente de la aplicación de consola o el Servicio de Windows. Luego, tiene la opción de llamar al proceso de trabajo desde una aplicación de consola y conectarlo al Programador de Windows, o usar un Servicio de Windows.

Descubrirá que programar un servicio de Windows no es divertido. Un escenario bastante común es que tiene un proceso de ejecución prolongada que desea ejecutar periódicamente. Pero, si está procesando una cola, entonces realmente no desea que dos instancias del mismo trabajador procesen la misma cola. Por lo tanto, debe administrar el temporizador para asegurarse de que si su proceso de ejecución prolongada ha durado más que el intervalo de temporizador asignado, no se reinicia hasta que el proceso existente haya finalizado.

Después de haber escrito todo eso, piensas, ¿por qué no usé Thread.Sleep? Eso me permite dejar que el hilo actual siga ejecutándose hasta que haya finalizado y luego se activa el intervalo de pausa, el hilo se pone en suspensión y se inicia de nuevo después del tiempo requerido. ¡Ordenado!

Luego, lee todos los consejos en Internet con muchos expertos que le dicen que realmente es una mala práctica de programación:

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

Así que te rascarás la cabeza y pensarás para ti mismo, WTF, Deshacer pagos pendientes -> Sí, estoy seguro -> Deshacer todo el trabajo de hoy ... maldita sea, maldita sea ...

Sin embargo, me gusta este patrón, incluso si todos piensan que es una mierda:

Método OnStart para el enfoque de un solo hilo.

protected override void OnStart (string args) {

   // Create worker thread; this will invoke the WorkerFunction
   // when we start it.
   // Since we use a separate worker thread, the main service
   // thread will return quickly, telling Windows that service has started
   ThreadStart st = new ThreadStart(WorkerFunction);
   workerThread = new Thread(st);

   // set flag to indicate worker thread is active
   serviceStarted = true;

   // start the thread
   workerThread.Start();
}

El código crea una instancia de un hilo separado y le adjunta nuestra función de trabajo. Luego inicia el hilo y deja que el evento OnStart se complete, para que Windows no crea que el servicio está bloqueado.

Método de trabajo para el enfoque de un solo hilo.

/// <summary>
/// This function will do all the work
/// Once it is done with its tasks, it will be suspended for some time;
/// it will continue to repeat this until the service is stopped
/// </summary>
private void WorkerFunction() {

   // start an endless loop; loop will abort only when "serviceStarted"
   // flag = false
   while (serviceStarted) {

      // do something
      // exception handling omitted here for simplicity
      EventLog.WriteEntry("Service working",
         System.Diagnostics.EventLogEntryType.Information);

      // yield
      if (serviceStarted) {
         Thread.Sleep(new TimeSpan(0, interval, 0));
      }
   }

   // time to end the thread
   Thread.CurrentThread.Abort();
}

Método OnStop para el enfoque de un solo hilo.

protected override void OnStop() {

   // flag to tell the worker process to stop
   serviceStarted = false;

   // give it a little time to finish any pending work
   workerThread.Join(new TimeSpan(0,2,0));
}

Fuente: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (Dead Link)

He estado ejecutando muchos servicios de Windows como este durante años y me funciona. Todavía no he visto un patrón recomendado con el que la gente esté de acuerdo. Solo haz lo que funcione para ti.

Rebecca
fuente
2
Realmente es posible que desee ejecutar su servicio con su propia cuenta de servicio. Si todo ejecuta un SERVICE o NETWORKSERVICE, le está otorgando permisos a su aplicación que probablemente no necesite (y eso puede poner en riesgo la seguridad no solo de un servidor sino de toda su red).
Matthew Whited
1
En efecto. ¿No creo haber dicho lo contrario?
Rebecca
4
De alguna manera insinuó lo contrario en su primer párrafo. La contraseña del usuario es necesaria para los servicios de la misma manera que para el programador de tareas si no está utilizando una de las cuentas integradas.
Nick Cox
1
@MatthewWhited La NT AUTHORITY\NetworkServicees una cuenta con privilegios limitados.
Ian Boyd
1
@IanBoyd, incluido cualquier permiso asignado a NetworkService relacionado con otras aplicaciones.
Matthew Whited
16

Alguna desinformación aquí. El Programador de Windows es perfectamente capaz de ejecutar tareas en segundo plano sin que aparezcan ventanas y sin necesidad de contraseña. Ejecútelo con la cuenta NT AUTHORITY \ SYSTEM. Utilice este interruptor schtasks:

/ ru SISTEMA

Pero sí, para acceder a los recursos de la red, la mejor práctica es una cuenta de servicio con una política de contraseña independiente que no caduque.

EDITAR

Dependiendo de su sistema operativo y los requisitos de la tarea en sí, es posible que pueda usar cuentas con menos privilegios que Localsystem con el /ru opción.

Del fino manual ,

/RU username

A value that specifies the user context under which the task runs. 
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM". 
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and 
"NT AUTHORITY\NETWORKSERVICE" are also valid values.

Programador de tareas 2.0 está disponible en Vista y Server 2008.

En XP y Server 2003, systemes la única opción.

Amit Naidu
fuente
2
Ejecute como Local Service(alias NT AUTHORITY\LocalService) en lugar de LocalSystem(alias .\LocalSystem). El primero tiene derechos limitados, mientras que el segundo es administrador
Ian Boyd
1
Sí, las cuentas adicionales LocalServicey NetworkServiceestán disponibles en schtasksVista v2 en adelante y deben preferirse siempre que sea posible. En ese momento, esto se refería a schtasksXP y Server 2003, que solo aceptan Systemcomo parámetro según la versión anterior del manual technet.microsoft.com/en-us/library/bb490996.aspx
Amit Naidu
En XP no puede ejecutar una tarea programada como SYSTEM. Buena suerte con eso. Este lo resume bien: cwl.cc/2011/12/run-scheduled-task-as-system.html
Pupsik
11

¿Cuál es la sobrecarga de iniciar y cerrar la aplicación? Cada dos minutos es bastante frecuente. Un servicio probablemente permitiría que el sistema funcione con más fluidez que ejecutar su aplicación con tanta frecuencia.

Ambas soluciones pueden ejecutar el programa cuando el usuario no está conectado, por lo que no hay diferencia. Sin embargo, escribir un servicio es algo más complicado que una aplicación de escritorio normal; es posible que necesite un cliente GUI separado que se comunique con la aplicación de servicio a través de TCP / IP, canalizaciones con nombre, etc.

Desde el punto de vista de un usuario, me pregunto cuál es más fácil de controlar. Tanto los servicios como las tareas programadas están prácticamente fuera del alcance de la mayoría de los usuarios no técnicos, es decir, ni siquiera se darán cuenta de que existen y se pueden configurar, detener, reprogramar, etc.

Marek Jedliński
fuente
10

En el desarrollo de .NET, normalmente empiezo desarrollando una aplicación de consola, que ejecutará todos los registros de salida en la ventana de la consola. Sin embargo, esta es solo una aplicación de consola cuando se ejecuta con el argumento de comando /console. Cuando se ejecuta sin este parámetro, actúa como un servicio de Windows, que seguirá ejecutándose en mi propio temporizador programado codificado personalizado.

Los servicios de Windows, en mi opinión, se utilizan normalmente para administrar otras aplicaciones, en lugar de ser una aplicación de larga duración. O ... son aplicaciones pesadas de ejecución continua como SQL Server, BizTalk, conexiones RPC, IIS (aunque IIS técnicamente descarga el trabajo a otros procesos).

Personalmente, prefiero las tareas programadas sobre los servicios de Windows para aplicaciones y tareas de mantenimiento repetitivas, como copia / sincronización de archivos, envío masivo de correo electrónico, eliminación o archivo de archivos, corrección de datos (cuando no hay otras soluciones disponibles).

Para un proyecto, he estado involucrado en el desarrollo de 8 o 9 servicios de Windows, pero estos se quedan en la memoria, inactivos, consumiendo 20 MB o más de memoria por instancia. Las tareas programadas harán su trabajo y liberarán la memoria de inmediato.

Dominic Zukiewicz
fuente
8

La palabra 'serv'ice comparte algo en común con' serv'er. Se espera que siempre esté ejecutándose y "sirva". Una tarea es una tarea.

Juego de rol. Si soy otro sistema operativo, aplicación o dispositivo y llamo a un servicio, espero que se esté ejecutando y espero una respuesta. Si yo (os, app, dev) solo necesito ejecutar una tarea aislada, entonces ejecutaré una tarea, pero si espero comunicarme, posiblemente comunicación bidireccional, quiero un servicio. Esto tiene que ver con la forma más efectiva de que dos cosas se comuniquen, o una sola cosa que quiera ejecutar una sola tarea.

Luego está el aspecto de la programación. Si desea que algo se ejecute a una hora específica, programe. Si no sabe cuándo lo va a necesitar, o si lo necesita "sobre la marcha", servicio.

Mi respuesta es de naturaleza más filosófica porque es muy similar a cómo los humanos interactúan y trabajan con otros. Cuanto más comprendamos el arte de la comunicación y las "entidades" comprendan su función, más fácil será esta decisión.

Dejando de lado toda la filosofía, cuando estás "haciendo prototipos rápidamente", como suele hacer mi departamento de TI, haces lo que sea necesario para llegar a fin de mes. Una vez que la creación de prototipos y la prueba de concepto están fuera del camino, generalmente en la planificación y el descubrimiento iniciales, debe decidir qué es más confiable para la sostenibilidad a largo plazo.

Bien, en conclusión, depende en gran medida de muchos factores, pero es de esperar que esto haya proporcionado información en lugar de confusión.

Dan Cortese
fuente
4

Un servicio de Windows no necesita que nadie inicie sesión, y Windows tiene instalaciones para detener, iniciar y registrar los resultados del servicio.

Una tarea programada no requiere que aprenda a escribir un servicio de Windows.

Mark Ransom
fuente
9
Las tareas programadas también se pueden ejecutar sin que el usuario haya iniciado sesión, pero se debe proporcionar la contraseña del usuario al agente de programación.
Marek Jedliński
1
@moodforaday A menos que la cuenta no haya pasado configurada (por ejemplo NT AUTHORITY\LocalService, o NT AUTHORITY\NetworkService). Cualquier contraseña proporcionada se ignora porque las cuentas no tienen contraseña.
Ian Boyd
4
  1. Es más fácil configurar y bloquear los servicios de Windows con los permisos correctos.
  2. Los servicios son más "visibles", lo que significa que todos (es decir, técnicos) saben dónde buscar.
Yo no
fuente
5
Su primer punto también se aplica a las tareas programadas. No estoy seguro de qué significa "más visible". Las tareas programadas se pueden ver tan fácilmente como los servicios.
w4g3n3r
@ w4g3n3r: La mayoría de la gente de tecnología sabe cómo mirar los servicios de Windows para ver qué se está ejecutando. Además, si es un servicio (y se está ejecutando), aparecerá en la lista normal del Administrador de tareas. Muy Muy pocas personas utilizan las tareas programadas.
NotMe
Además, los técnicos saben mirar en el visor de eventos cuando hay un problema. Las tareas programadas almacenan esa información en un archivo de registro en el sistema de archivos. Estoy dispuesto a apostar que la mayoría de la gente ni siquiera sabría dónde buscar eso.
NotMe
1
No estoy de acuerdo con "Muy, muy pocas personas utilizan las tareas programadas" a menos que tenga estadísticas. Los veo todo el tiempo. Para los no codificadores que necesitan ejecutar algo cada 2 minutos, simplemente navegan hasta Tareas programadas (la misma dificultad que para acceder a Servicios), pero para crear una nueva hay un Asistente. Entonces, todo lo que tienen que saber es dónde está el programa o el script y con qué frecuencia debe ejecutarse. Ahora, si sabe cómo codificar y tiene la máquina en una red, necesita proteger el inicio de sesión, necesita un manejo integrado para evitar múltiples instancias (si una se ejecuta durante 2 minutos), entonces optaría por un servicio.
Gary
4
"La mayoría de la gente de tecnología sabe cómo mirar los servicios de Windows para ver qué se está ejecutando" . Ese es uno de los problemas con los servicios; ejecutan todos los recursos del kernel y del usuario que consumen mucho tiempo simplemente para mantener un proceso en ejecución. Es por eso que Microsoft fusionó tantos servicios en un solo proceso como fue posible ( svchost.exe ); para eliminar el consumo innecesario de recursos simplemente por tener procesos.
Ian Boyd
2

¿Por qué no proporcionar ambos?

En el pasado, puse los bits 'centrales' en una biblioteca y envié una llamada a Whatever.GoGoGo () tanto en un servicio como en una aplicación de consola.

Con algo que disparas cada dos minutos, las probabilidades son decentes de que no esté haciendo mucho (por ejemplo, una función de tipo "ping"). Los contenedores no deberían contener mucho más que una única llamada a un método y algunos registros.


fuente
2

Esta es una pregunta antigua, pero me gustaría compartir con lo que me he enfrentado.

Recientemente me dieron el requisito de capturar la captura de pantalla de un radar (de un sitio web meteorológico) y guardarla en el servidor cada 10 minutos.

Esto requirió que usara WebBrowser. Por lo general, hago servicios de Windows, así que decidí hacer este servicio también, pero seguiría fallando. Esto es lo que vi en el Visor de eventos ruta del módulo de fallas del : C: \ Windows \ system32 \ MSHTML.dll

Como la tarea era urgente y tenía muy menos tiempo para investigar y experimentar, decidí usar una aplicación de consola simple y la activé como una tarea y se ejecutó sin problemas.

Me gustó mucho el artículo de Jon Galloway recomendado en la respuesta aceptada por Mark Ransom.

Recientemente, las contraseñas de los servidores se cambiaron sin reconocerme y todos los servicios no se ejecutaron porque no pudieron iniciar sesión. Entonces, las personas que afirman en el artículo comentan que esto es un problema. Creo que los servicios de Windows pueden enfrentar el mismo problema (por favor corríjame si me equivoco, solo soy un novato)

También lo mencionado, si se usa el programador de tareas, aparecen ventanas o la ventana de la consola. Nunca me he enfrentado a eso. Puede aparecer, pero al menos es muy instantáneo.

Plata
fuente
Pensé que el artículo de Jon Galloway tenía algunos puntos positivos. Además, para la queja sobre tareas programadas que no se ejecutan debido a un cambio de contraseña o lo que sea, es posible responder a una tarea programada que no se ejecuta, para que pueda notificar a los usuarios o lo que le gustaría hacer. Vea la solución aquí: superuser.com/questions/249103/...
Dan Csharpster
1

Generalmente, el mensaje central es y debe ser que el código en sí debe ser ejecutable desde todos y cada uno de los "desencadenadores / clientes". Por lo tanto, no debería ser ciencia de cohetes cambiar de un enfoque a otro.

En el pasado usábamos más o menos siempre los servicios de Windows, pero dado que también más y más clientes se cambian a Azure paso a paso y el cambio de una aplicación de consola (implementada como una tarea programada) a un WebJob en Azure es mucho más fácil que desde un servicio de Windows, por ahora nos centramos en las tareas programadas. Si nos encontramos con limitaciones, simplemente aumentamos el proyecto de servicio de Windows y llamamos a la misma lógica desde allí (siempre que los clientes estén trabajando en OnPrem ..) :)

BR, y

ynnok
fuente
0

Los servicios de Windows quieren más paciencia hasta que esté listo. Tiene un poco de instalación y depuración. No tiene rostro. Si necesita una tarea que debe realizarse cada segundo, minuto u hora, debe elegir el Servicio de Windows.

La tarea programada se desarrolla rápidamente y tiene una cara. Si necesita una tarea diaria o semanal, puede utilizar Tarea programada.

Oguzhan KIRCALI
fuente