Servicio de Windows con temporizador

He creado un servicio de Windows con temporizador en c # .net. funciona bien mientras depuro / construyo el proyecto en Visual Studio pero no realiza su operación después de la instalación.

¿Cuál podría ser la razón detrás de esto?

código:

public partial class Service1 : ServiceBase { FileStream fs; StreamWriter m_streamWriter; Timer tm = new Timer(); public Service1() { InitializeComponent(); this.ServiceName = "timerservice"; tm.Interval = 2000; tm.Tick += new EventHandler(PerformOperations); tm.Start(); fs = new FileStream(@"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write); m_streamWriter = new StreamWriter(fs); m_streamWriter.BaseStream.Seek(0, SeekOrigin.End); } private void PerformOperations(object sener, EventArgs e) { //StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true); try { OdbcConnection con = new OdbcConnection("DSN=liquor_data"); OdbcDataAdapter adp = new OdbcDataAdapter("", con); DataSet ds = new DataSet(); string sql = "select * from item_group"; adp.SelectCommand.CommandText = sql; adp.Fill(ds, "item_group"); foreach (DataRow dr in ds.Tables["item_group"].Rows) { // swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); //Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); } m_streamWriter.Flush(); } catch (Exception ex) { // swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); } } } } 

El primer enfoque con el servicio de Windows no es fácil …

Hace mucho tiempo, escribí un servicio de C #.

Esta es la lógica de la clase de servicio (probado, funciona bien):

 namespace MyServiceApp { public class MyService : ServiceBase { private System.Timers.Timer timer; protected override void OnStart(string[] args) { this.timer = new System.Timers.Timer(30000D); // 30000 milliseconds = 30 seconds this.timer.AutoReset = true; this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed); this.timer.Start(); } protected override void OnStop() { this.timer.Stop(); this.timer = null; } private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { MyServiceApp.ServiceWork.Main(); // my separate static method for do work } public MyService() { this.ServiceName = "MyService"; } // service entry point static void Main() { System.ServiceProcess.ServiceBase.Run(new MyService()); } } } 

Le recomiendo que escriba su trabajo de servicio real en un método estático separado (por qué no, en una aplicación de consola … simplemente agregue referencia), para simplificar la depuración y limpiar el código de servicio.

Asegúrese de que el intervalo sea suficiente y escriba en el registro SOLAMENTE en anulaciones OnStart y OnStop.

¡Espero que esto ayude!

Debes poner tu código principal en el método OnStart .

Esta otra respuesta SO podría ayudar.

Tendrá que poner algún código para habilitar la depuración en Visual Studio mientras mantiene su aplicación válida como un servicio de Windows. Este otro hilo SO cubre el problema de depurar un servicio de Windows.

EDITAR :

Consulte también la documentación disponible aquí para el método OnStart en MSDN donde se puede leer esto:

No use el constructor para realizar el procesamiento que debería estar en OnStart . Use OnStart para manejar toda la inicialización de su servicio. Se llama al constructor cuando se ejecuta el ejecutable de la aplicación, no cuando se ejecuta el servicio. El ejecutable se ejecuta antes de OnStart . Cuando continúa, por ejemplo, el constructor no se vuelve a llamar porque SCM ya tiene el objeto en la memoria. Si OnStop libera recursos asignados en el constructor en lugar de en OnStart , los recursos necesarios no se crearán nuevamente la segunda vez que se llame al servicio.

Aquí hay un ejemplo de trabajo en el que la ejecución del servicio se inicia en el evento OnTimedEvent del temporizador que se implementa como delegado en la clase ServiceBase y la lógica del temporizador se encapsula en un método llamado SetupProcessingTimer ():

 public partial class MyServiceProject: ServiceBase { private Timer _timer; public MyServiceProject() { InitializeComponent(); } private void SetupProcessingTimer() { _timer = new Timer(); _timer.AutoReset = true; double interval = Settings.Default.Interval; _timer.Interval = interval * 60000; _timer.Enabled = true; _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); } private void OnTimedEvent(object source, ElapsedEventArgs e) { // begin your service work MakeSomething(); } protected override void OnStart(string[] args) { SetupProcessingTimer(); } ... } 

El intervalo se define en app.config en minutos:

    1