Member 13378284 Ответов: 2

Как я могу объявить много таймеров и остановить таймер, когда время истекло в C#?


Я постараюсь описать его как можно подробнее. заранее спасибо.

Есть ли способ объявить много таймеров, например, с помощью массива или других методов? и остановить таймер, когда таймер истекает или время истекло?

Я пробовал t. Stop (); и другие методы таймера, но я не могу заставить его работать. этот код показывает окно сообщения каждую минуту или независимо от того, что пользователь ввел в таймер. Проблема в том, что я могу остановить таймер, когда у меня есть несколько таймеров.

У меня есть форма это позволяет пользователю ввести таймер, например 1 минуту, эта форма всплывает, когда я выбираю строку в представлении таблицы данных, код преобразует часы или минуты в секунды и работает нормально.

private void button1_Click(object sender, EventArgs e)
    {
        if (textBox1.Text == "")
        {
            MessageBox.Show("Please Indicate How Many Minutes/Hours.");
        }
        else
        {
            string desu = textBox1.Text;
            int temp = 0;
            if (int.TryParse(desu, out temp))
            {
                if (comboBox1.Text == "Hours")
                {
                    //hours to seconds
                    time = temp * 3600;
                    eta = desu + "Hours";

                    this.Close();
                }
                else if (comboBox1.Text == "Minutes")
                {
                    //minutes to seconds
                    time = temp * 60;
                    eta = desu + "Minutes";

                    this.Close();
                }
            }
            else
            {
                MessageBox.Show("Please enter a valid integer");
            }
        }
    }


после ввода таймера через 1 минуту появится окно сообщения и остановит текущий таймер.

вот метод, который вызывается при запуске таймера

public void Start()
    {


        ETA_Input frm = new ETA_Input(this);
        startTime = DateTime.Now;
        t = new System.Timers.Timer(1000 * f);
        t.Elapsed += timer_Elapsed;
        t.Enabled = true;

    }


а затем вот где он запускает форму, в которой вы можете ввести часы или минуты и передать значение строки в представление списка, изменив одно из значений в datagridview и в databse.

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        ETA_Input frm = new ETA_Input(this);
        frm.ShowDialog();
        if (frm.time != 0)
        {
            string name = dataGridView1.CurrentRow.Cells[0].Value.ToString();
            int deku = Int32.Parse(name);
            string constring = "server=localhost;database=dbhorizon;uid=root;password=1234";
            string Query = "update tblUserIdd set User_Available = 'Ongoing' where User_ID='" + deku + "' ";

            MySqlConnection conDatabase = new MySqlConnection(constring);
            MySqlCommand cmdDatabase = new MySqlCommand(Query, conDatabase);
            MySqlDataReader myReader;

            conDatabase.Open();
            myReader = cmdDatabase.ExecuteReader();
            dgvref();

            string id = dataGridView1.CurrentRow.Cells[0].Value.ToString();
            string naem = dataGridView1.CurrentRow.Cells[1].Value.ToString();
            string field = dataGridView1.CurrentRow.Cells[2].Value.ToString();

            f = frm.time;

            Start();



            seconds = string.Format("{0:HH:mm:ss tt}", DateTime.Now);


            string[] row = { id, naem, field, seconds, frm.eta,custb  };
            var listViewItem = new ListViewItem(row);
            listView1.Items.Add(listViewItem);


        }

    }


а вот событие Time elapsed, в котором я намеревался остановить таймер, что время истекло, и удалить элемент в представлении списка при изменении значения в datagridview в базу данных. я также не могу удалить элемент, где время истекло или прошло.


void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        TimeSpan timeSinceStart = DateTime.Now - startTime;
        MessageBox.Show("A Service is finished");

        string name = dataGridView1.CurrentRow.Cells[0].Value.ToString();
        int deku = Int32.Parse(name);
        string constring = "server=localhost;database=dbhorizon;uid=root;password=1234";
        string Query = "update tblUserIdd set User_Available = 'Available' where User_ID='" + deku + "' ";

        MySqlConnection conDatabase = new MySqlConnection(constring);
        MySqlCommand cmdDatabase = new MySqlCommand(Query, conDatabase);
        MySqlDataReader myReader;

        conDatabase.Open();
        myReader = cmdDatabase.ExecuteReader();
        dgvref();
    }


Что я уже пробовал:

Я перепробовал кучу вещей, которые, как я выяснил, на самом деле не связаны с тем, что я хочу делать.

2 Ответов

Рейтинг:
16

OriginalGriff

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


Рейтинг:
0

Graeme_Grant

Запуск большого количества таймеров может истощить ресурсы. Было бы разумнее иметь один таймер и список задач. Затем через определенный промежуток времени проверяет, нужно ли запускать задачу, и выполняет ее. Ваша задача/задание может выглядеть следующим образом:

class Job
{
    public bool Activated { get; set; }
    public Task<Action> UnitOfWork { get; set; }
    public DateTime StartAt { get; set; }
}

Тогда премьер:
public static List<Job> Jobs { get; set; } = new List<Job>();

private static void AddJob()
{
    Jobs.Add(new Job
    {
        StartAt = DateTime.Now + new TimeSpan(0, 0, 10),
        UnitOfWork = (Task<Action>)DoATask()
    });
}

private static async Task DoATask()
{
    // do async work here...
}

И использовать, устанавливая таймер на 1-секундные интервалы для периодической проверки:
private static void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    var newJobs = Jobs.Where(x => x.StartAt <= DateTime.Now && !x.Activated);
    foreach (var job in newJobs)
    {
        job.Activated = true;
        job.UnitOfWork.Start();
    }
}

Это модель "огонь и забудь". Если несколько заданий заданы в одно и то же время запуска, все они будут запущены. Фактическая работа, которая выполняется, выполняет все отслеживание и очистку.