Как я могу заставить приложение никогда не закрываться и выполнять процедуру каждый час? - PullRequest
0 голосов
/ 02 июня 2018

Как насчет !, кто-то может помочь мне с этим, пожалуйста, я ищу, чтобы через консольное приложение каждый раз, когда «00» минут (то есть каждый час), хранимая процедура выполнялась только один раз (Я не знаю, почему он выполняется более 1 раза, так как это процедура вставки), и я также хочу, чтобы приложение никогда не закрывалось, позже я хочу создать службу и выполнить больше процедур, но мне это нужно какое-то время.Что я делаю не так?, Идея в том, что в консоли напишите «Ожидание вставки в пакете», а когда придет время, выполните процедуру и напишите «Успешная вставка», затем продолжайте вводить «Ожидание вставки в пакете», поканаступает следующий час.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading;

namespace Job_StoreProcedure
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection conn = new SqlConnection
                  ("Server=localhost\\SQLEXPRESS;Database=VIDEOJUEGOS;Integrated Security=SSPI"))
            {
                conn.Open();
                for (int i = 0; i - 1 < i++; i++)
                {
                    Console.WriteLine("Waiting for insertion in batch");
                    if (DateTime.Now.ToString("mm") == "00")
                    {
                        SqlCommand cmd = new SqlCommand("usp_virtualX", conn);
                        cmd.CommandType = CommandType.StoredProcedure;

                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            while (rdr.Read())
                            {
                                Console.WriteLine("Successful insertion");
                            }
                        }
                    }
                }
            }
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 03 июня 2018

Просто используйте таймеры.

using System.Timers;
//...
class Program
{
    private static Timer MainTimer = new Timer(1000 * 60 * 60);

    static void Main(string[] args)
    {
        Console.WriteLine("Waiting for insertion in batch");

        MainTimer.Elapsed += MainTimer_Elapsed;

        // Wait for the start of the hour. Then start the one-hour MainTimer. 
        var tmptimer = new Timer() { Interval = 1000 };
        tmptimer.Elapsed += (sender, e) =>
        {
            if (DateTime.Now.Minute == 0)
            {
                MainTimer.Start();              
                tmptimer.Stop();
                MainTimer_Elapsed(null, null);  // Call manually first time 
            }
        };
        tmptimer.Start();

        while (true)
            Console.Read();
    }

    private static void MainTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        using (SqlConnection conn = new SqlConnection ("Server=localhost\\SQLEXPRESS;Database=VIDEOJUEGOS;Integrated Security=SSPI"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand("usp_virtualX", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    Console.WriteLine("Successful insertion");
                }
            }
        }
        Console.WriteLine("Waiting for insertion in batch");

        GC.Collect();
    }
}
0 голосов
/ 03 июня 2018

Это становится значительно проще, если вы принимаете async / await и используете Task.Delay:

Например, вы можете:

static async Task Main(string[] args) //async Main supported in C#7
{
    var now = DateTime.UtcNow; //always use UTC, calculating timezones costs time
    var startOfCurrentTimePeriod = 
        new DateTime(now.Year, 
                     now.Month, 
                     now.Day, 
                     now.Hour, 
                     now.Minute, 
                     now.Second, 
                     0,         //set this ms part to 0
                     DateTimeKind.Utc);
    var triggerTime = oClock.AddSeconds(1); //when we want to run our action
    while (true)
    {
        var waitTime = triggerTime - DateTime.UtcNow;
        if (waitTime > TimeSpan.Zero) //if we have a negative wait time, just go
        {
            await Task.Delay(waitTime);
        }
        triggerTime = triggerTime.AddSeconds(1); //set the next time
        //perform action
        Console.WriteLine($"the time is : {triggerTime}");
    }
}

Преобразование должно быть тривиальнымэтот код срабатывает на час, а не на второй.Хорошее упражнение.

0 голосов
/ 03 июня 2018

Как уже упоминалось в комментариях, лучший способ удовлетворить ваши потребности - удалить цикл и выполнить операцию только один раз, а также создать расписание задач для запуска программы в нужное время.

Если вам нужно продолжить с тем жеПодходят к некоторым проблемам, с которыми должен столкнуться этот код:

Каждый час он будет вставлен более одного раза, если операция вставки занимает менее минуты.Пример: скажем, если вставка начинается в 1:00:00 и заканчивается в 1:00:20, программа начнет следующую итерацию и вставит снова, потому что mm по-прежнему равен 00. Одним из решений является перевод потока в спящий режим для1 минута изнутри внешнего цикла.

С этим кодом вы столкнетесь еще с одной проблемой: соединение будет закрыто, если какое-то время не используется.Также, если вставка не удалась, программа завершит работу из-за отсутствия обработки ошибок.Возможно, вы захотите открыть и закрыть соединение во время выполнения операции (то есть внутри цикла) и использовать обработку ошибок, чтобы приложение продолжало работать в случае возникновения исключительной ситуации.

...