当C#中的时间到期时,如何声明多个计时器并停止计时器? [英] How can I declare many timers and stop a timer when a time had expired in C#?

查看:111
本文介绍了当C#中的时间到期时,如何声明多个计时器并停止计时器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会尽可能详细地说明我的描述。提前谢谢。



有没有办法声明许多计时器,比如使用数组或其他方法?当计时器到期或时间结束时停止计时器?



我试过t.Stop();和其他计时器方法,但我不能让它工作。此代码每分钟显示消息框或用户在计时器中输入的任何内容。问题是,当我有多个计时器时,我似乎可以停止计时器。



我有表单,允许用户输入计时器,例如1分钟,当我在数据网格视图中选择一行时弹出此表单,代码将小时或分钟转换为秒和工作正常。



I'll make my description as detailed as possible. thanks in advance.

Is there a way to declare many timers like using array or other methods? and stop the timer when timer expires or time has elapsed?

I have tried t.Stop(); and other timer methods but i cant make it work. this code shows the message box every minute or whatever the user inputted in the timer. The problem is that i can seem to stop a timer when i have multiple timers.

I have a form that allows the user to input the timer,for example 1 minute, this form pops up when i selected a row in the data grid view, the code converts the Hours or minutes into seconds and is working fine.

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分钟后会出现一个消息框并停止当前定时器。



这是启动计时器时调用的方法





after you input the timer, after 1 minute a message box will appear and stop the current timer.

here is the method to call when starting the timer

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和数据库中的一个值。





and then here is where it trigger the form where you can input hours or minutes, and pass the row value to the list view while changing one of the value in the datagridview and to the 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);


        }

    }





这是时候了已经过去的事件,我打算停止时间已到期的计时器,并在将datagridview中的值更改为数据库时删除列表视图中的项目。我似乎也无法删除时间已过期或已过去的项目。







and here is the time elapsed event where i intended to stop the timer that the time has expired and remove the item in the list view while changing a value in the datagridview to the database. i cant also seem to remove the item where the time has expired or elapsed.


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();
    }





我的尝试:



我尝试了很多东西,我发现它与我想做的事情没有关系。



What I have tried:

Ive tried a bunch of stuffs which i found out is not really related to what i want to do.

推荐答案

而不是每个都创建新的计时器时间 - 这是一个坏主意,它们是Windows中的稀缺资源 - 设置结束时间的DateTime集合并使用单个运行计时器来针对DateTime检查每个时间。现在

当您找到时经过一段时间后,将其从集合中删除并进行处理。计时器继续运行并继续检查每个Tick事件的集合,直到它找到工作为止。
Instead of creating new timers each time - which is a bad idea, they are a scarce resource in Windows - set up a DateTime collection of end times and use a single running timer to check each of them against DateTime.Now
When you find an elapsed period, remove it from the collection and do your processing. The timer continues running and keeps checking the collection each Tick event until it find work to do.


运行大量的Timers可能会耗尽资源。拥有一个计时器和一个任务列表会更明智。然后在一个时间间隔内,检查是否要启动任务,执行任务。你的任务/工作可能如下所示:

Running a lot of Timers can drain resources. It would be wiser to have a single timer and a list of Tasks. Then on an interval, checks if a Task is to be started, executes the task. Your Task/Job could look like this:
class Job
{
    public bool Activated { get; set; }
    public Task<Action> UnitOfWork { get; set; }
    public DateTime StartAt { get; set; }
}



然后填写:


Then to prime:

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秒间隔进行定期检查:


And to use, setting the timer to 1 second intervals for periodical checking:

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();
    }
}



这是一个消防模型。如果多个作业设置相同的开始时间,它们将全部运行。运行的实际作业执行所有跟踪和清理。


This is a fire and forget model. If multiple jobs are set the same start time, they will all run. The actual job that runs does all the tracking and cleanup.


这篇关于当C#中的时间到期时,如何声明多个计时器并停止计时器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆