How to create a process that runs daily using C #?

4

What happens is that I have to generate a report daily from some data obtained from the BD. I generate the report and send it by mail from a button, now the application will be hosted on a server, then it is required that once it is executed and the report is sent, wait 24 hours and send the report again. automatically, that is, without someone having to enter the server and press the button again to send it again. (Any ideas on how to do it?)

is a WindowsForm which will be hosted on a server so it will be running at all times.

    
asked by Alberto Rojas 05.10.2016 в 18:57
source

6 answers

1

This is definitely not the best way to proceed with a recurring task.

If you do not have another, your first option is to create a task in the windows task manager and choose the executable that will perform the action, but that executable will have to perform the action of the button click automatically when opening it.

A good option is to use SSIS to generate a package that is executed from time to time by a job more in shape in your server and there you will have more flexibility also to extract data from the base, transform them and generate notifications in a much more stable and robust environment.

Another open source alternative is Pentaho that allows you to perform the same tasks as the previous one but without paying a penny.

I hope your comments will be helpful.

    
answered by 05.10.2016 в 22:10
1

we solved it in the following way:

We developed a console program that generates several reports and sends them by email depending on the parameters it receives as arguments. See more .

Initially we used Windows Forms, but frequently it hung up; In addition, the console program uses fewer resources and runs faster.

To send the program call we use the Windows Task Scheduler, this tool by itself allows you to configure the parameters you want to send, execution schedules, execution frequency, allows you to run the program when you turn on the computer, it will be turned off at the time it should be executed, and many other useful functions, I recommend it.

If you need more details let me know.

Luck

How to open the Task Scheduler in different versions of Windows (English)

Use of the task scheduler (Video in Spanish) .

    
answered by 06.10.2016 в 07:27
1

Creating a Windows Service with a Timer of 24 hours of execution, that is to say, that the method that generates the reports is executed.

This link provides all the necessary information so that You can create the project and execute the necessary methods.

That is, now you will have two ways to get the report, one by means of the button and another by means of the automatic task of the Windows Service.

    
answered by 12.10.2016 в 19:39
0

The ideal method for this to solve this task is the creation of a Windows Service, here I leave you theoretical information on this Link , and how to install the Windows Service on the server Link .

System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 60000; // 60 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
    
answered by 12.10.2016 в 21:36
0

To avoid having to modify the code in the application, you could create an integration service (Integration Services Project SSIS), and execute it in the sql server agent, that way you would have a more secure access to the data, < a href="https://www.youtube.com/watch?v=JbC_ronWGXo"> Here you can find more information.

    
answered by 12.10.2016 в 21:45
0

I leave a solution to the problem from the windows service approach, which is the missing example.

This is an implementation of a windows service that runs a scheduled task (shows the time every 15 seconds per console) with the Quartz library that I think is powerful enough to plan tasks.

In the code I left the external references that I was taking in the code to make it as simple as possible.

  • Program.cs (Application entry point) [1]

    using System;
    using System.Reflection;
    using System.ServiceProcess;
    using System.Threading;
    
    namespace ServicioDiario
    {
        /*
         * El ejemplo se basa en una forma para depurar servicios windows de manera simple: https://stackoverflow.com/questions/125964/easier-way-to-debug-a-windows-service
         */
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            static void Main()
            {
                ServiceBase[] servicesToRun;
                servicesToRun = new ServiceBase[] 
                {
                    new Service1()
                };
    
                if (Environment.UserInteractive)
                {
                    RunInteractive(servicesToRun);
                }
                else
                {
                    ServiceBase.Run(servicesToRun);
                }
            }
    
            static void RunInteractive(ServiceBase[] servicesToRun)
            {
                Console.WriteLine("* El servicio esta corriendo en modo interactivo *");
                Console.WriteLine();
    
                MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart",
                    BindingFlags.Instance | BindingFlags.NonPublic);
                foreach (ServiceBase service in servicesToRun)
                {
                    Console.Write("Iniciando servicio {0}...", service.ServiceName);
                    onStartMethod.Invoke(service, new object[] { new string[] { } });
                    Console.Write("Iniciado");
                }
    
                Console.WriteLine();
                Console.WriteLine(
                    "Presione una tecla para detener el servicio y el proceso...");
                Console.ReadKey();
                Console.WriteLine();
    
                MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop",
                    BindingFlags.Instance | BindingFlags.NonPublic);
                foreach (ServiceBase service in servicesToRun)
                {
                    Console.Write("Deteniendo {0}...", service.ServiceName);
                    onStopMethod.Invoke(service, null);
                    Console.WriteLine("Detenido");
                }
    
                Console.WriteLine("Todos los servicios planificado estan detenidos.");
                // Permanezco un segundo para que pueda ver el mensaje.
                Thread.Sleep(1000);
            }
        }
    }
    
  • Work.cs (Class that will do the dirty work) [3]

    using System;
    using Quartz;
    
    namespace ServicioDiario
    {
        /*
         * Libreria recomendada para planificacion
         * https://www.quartz-scheduler.net/
         */
        public class Trabajo : IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                //Realizar la tarea planificada.
                System.Console.WriteLine("Hora: " + DateTime.Now.ToString("hh:mm:ss"));
            }
        }
    }
    
  • Planner.cs (Class used to manipulate the start and end of planning)

    using Quartz;
    using Quartz.Impl;
    
    namespace ServicioDiario
    {
        public class Planificador
        {
            public void Iniciar()
            {
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
                scheduler.Start();
    
                IJobDetail job = JobBuilder.Create<Trabajo>().Build();
                //Cada 15 segundos
                ITrigger trigger = TriggerBuilder.Create()
                       .WithSimpleSchedule(a => a.WithIntervalInSeconds(15).RepeatForever())
                       .Build();
    
                // Cada un dia
                //ITrigger trigger = TriggerBuilder.Create()
                //       .WithSimpleSchedule(a => a.WithIntervalInHours(24).RepeatForever())
                //       .Build();
    
                scheduler.ScheduleJob(job, trigger);
            }
    
            public void Detener()
            {
                IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
                scheduler.Shutdown();
            }
        }
    }
    
  • Service1.cs (service that is created by default with the windows service template) [4]

        using System.ServiceProcess;
    
    namespace ServicioDiario
    {
        /*
         * Codigo fuente basado en el siguiente enlace en ingles: http://www.codingdefined.com/2016/08/schedule-tasks-as-windows-service-using.html
         */
        public partial class Service1 : ServiceBase
        {
            Planificador plan;
    
            public Service1()
            {
                InitializeComponent();
            }
    
            protected override void OnStart(string[] args)
            {
                plan = new Planificador();
                plan.Iniciar();
            }
    
            protected override void OnStop()
            {
                if (plan != null)
                {
                    plan.Detener();
                }
            }
        }
    }
    

Note: In this example it is necessary to change the application type to console so you can show the results and do the tests [2].

As a final remark: there is a whole debate about using the task scheduler, a timer or a windows service. In my experience, the use depends on how much control and what monitoring you should do to the task (s). While more tasks, related to an application, you should plan with different periods of execution and greater control, the windows service approach is better.

References:

[1] link

[2] link

[3] link

[4] link

    
answered by 31.05.2017 в 19:35