简体   繁体   English

我有一个C#Windows窗体应用程序,希望用户能够安排重复任务

[英]I have a C# Windows Forms Application and I want the user to be able to schedule a recurring task

My application sends out an email based on data from the entered form on the UI. 我的应用程序根据UI上输入的表单中的数据发送电子邮件。 The UI also allows them to "schedule" this as a job. 用户界面还允许他们“安排”这项工作。 I don't really want to use outside classes, eg Quartz. 我真的不想使用外部类,例如Quartz。 I also don't want to use the task scheduler as this would require completely rewriting my app... I understand that this can be done with timers, and I have attempted to use the Windows.Forms.Timer, however, I am not getting the desired results. 我也不想使用任务计划程序,因为这将需要完全重写我的应用程序……我知道这可以通过计时器来完成,并且我尝试使用Windows.Forms.Timer,但是,我不是获得预期的结果。 I want it to run at the user specified interval and time, until the set end date. 我希望它以用户指定的时间间隔和时间运行,直到设置的结束日期。

private void Submit_Btn_Click(object sender, EventArgs e)
    {
        bool run = false;
        Location_Alert_Timer.Tick += new EventHandler(Location_Alert_Timer_Tick);

        if (Schedule_Chk.Checked == true)
        {
            run = true;

            if (Recur_Txt.Text != "" || Recur_Txt.Text != "0")
            {
                while (run == true)
                {

                    if ((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text)))
                    {
                        //Execute_Command();
                        DateTime dt1;
                        DateTime dt2;
                        TimeSpan ts = new TimeSpan(Convert.ToInt16(Recur_Txt.Text),0,0,0);
                        //TimeSpan ts = new TimeSpan(0,0,30);
                        dt1 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm"));
                        dt2 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text);
                        if  (dt1 >= dt2)
                        {
                            Execute_Command();
                            Location_Alert_Timer.Interval = (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000").Add(ts) - DateTime.Now).Milliseconds;
                            Location_Alert_Timer.Start();
                            while (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
                            {
                                Application.DoEvents();
                            }
                        }
                        else
                        {
                            Location_Alert_Timer.Interval = (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000") - DateTime.Now).Milliseconds;
                            Location_Alert_Timer.Start();
                            while (exitFlag == false)
                            {
                                Application.DoEvents();
                            }
                        }
                    }
                    else
                    {
                        Location_Alert_Timer.Stop();
                        run = false;
                    }
                }
            }
            else
            {
                Execute_Command();
            }
        }
        else
        {
            Execute_Command();
        }
    }

    void Location_Alert_Timer_Tick(object sender, EventArgs e)
    {
        if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
        {
            Execute_Command();
        }
        else
        {
            exitFlag = true;
        }
    }

My timer events do not seem to be firing right and I know it is because I have set them up incorrectly... 我的计时器事件似乎触发不正确,我知道这是因为我没有正确设置它们...

Here is the form UI: 这是表单UI: 表单用户界面

If anyone has a similar implementation in the future, @itsmatt's explanation led me to rewrite my whole event, from the ground up...below is the final implementation, and it works fantastically: 如果将来有人实现类似的实现,则@itsmatt的解释会导致我从头开始重写整个事件...下面是最终的实现,并且效果非常好:

        private void Submit_Btn_Click(object sender, EventArgs e)
    {
        bool run = false;


        if (Schedule_Chk.Checked == true)
        {
            run = true;

            if (Recur_Txt.Text != "" || Recur_Txt.Text != "0")
            {
                while (run == true)
                {
                    if ((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text)))
                    {
                        DateTime dt1;
                        DateTime dt2;
                        TimeSpan ts = new TimeSpan(Convert.ToInt16(Recur_Txt.Text),0,0,0);
                        dt1 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm"));
                        dt2 = Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text);
                        if (dt1 >= dt2)
                        {
                            Execute_Command();
                            Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000").Add(ts) - DateTime.Now).TotalMilliseconds);
                            Location_Alert_Timer.Start();
                            timerActive = true;
                            TimerHold();
                        }
                        else
                        {
                            Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text + ":00.000") - DateTime.Now).TotalMilliseconds);
                            singleuse = true;
                            Location_Alert_Timer.Start();
                            timerActive = true;
                            TimerHold();
                            MessageBox.Show(DateTime.Now.ToString());
                            MessageBox.Show(DateTime.Now.Add(ts).ToString());
                            MessageBox.Show((Convert.ToDateTime(DateTime.Now.Add(ts).ToString()) - DateTime.Now).TotalMilliseconds.ToString());
                            Location_Alert_Timer.Interval = Convert.ToInt32((Convert.ToDateTime(DateTime.Now.Add(ts).ToString()) - DateTime.Now).TotalMilliseconds);
                            Location_Alert_Timer.Start();
                            timerActive = true;
                            TimerHold();
                        }
                    }
                    else
                    {
                        Location_Alert_Timer.Stop();
                        run = false;
                    }
                }
            }
        }
    }

    public void TimerHold()
    {
        while (timerActive)
        {
            Application.DoEvents();
        }
    }

    void Location_Alert_Timer_Tick(object sender, EventArgs e)
    {
        if (singleuse)
        {
            if (uses < 1)
            {
                if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
                {
                    uses++;
                    //DoItOnce();
                    Execute_Command();
                }
                else
                {
                    timerActive = false;
                }
            }
            else
            {
                singleuse = false;
                timerActive = false;
                Location_Alert_Timer.Stop();
            }
        }
        else
        {
            if (Convert.ToDateTime(DateTime.Now.ToString("MM/dd/yyyy HH:mm")) <= Convert.ToDateTime(End_Date.Value.ToString("MM/dd/yyyy") + " " + Recur_Time_Txt.Text))
            {
                //DoIt();
                Execute_Command();
            }
            else
            {
                timerActive = false;
            }
        }
    }

what about using something like this example? 使用类似这个例子的东西怎么办?

A-Simple-Scheduler-in-Csharp A-简单的调度器功能于Csharp的

@kclewis Registering the tick event handler in the submit button click handler like you have will result in Location_Alert_Timer_Tick() being called once the first time the button is clicked, twice the next time, etc. It is registering the same callback function over and over, which results in multiple calls to that when the tick event is raised. @kclewis像您一样在提交按钮单击处理程序中注册滴答事件处理程序,将导致第一次单击该按钮一次,再次单击两次则调用Location_Alert_Timer_Tick(),等等。它一遍又一遍地注册相同的回调函数,当出现tick事件时,会导致对该调用的多次调用。 Instead, += that event handler at init time (could be in the constructor or some other setup() function). 而是在初始化时+ =该事件处理程序(可以在构造函数中或其他一些setup()函数中)。 That way you get one and only one function call to Location_Alert_Timer_Tick() when the timer tick event is raised. 这样,当计时器滴答事件触发时,您将只有一个函数调用Location_Alert_Timer_Tick()。 Posted via community wiki for @itsmatt 通过社区Wiki发布@itsmatt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C# 在高效的 Windows 服务中安排重复任务的最佳方式 - C# Best way to schedule recurring task in an efficient windows service 如何使用Windows Task Scheduler在C#中创建/修改重复任务? - How do I create/modify a recurring task in C# using Windows Task Scheduler? 我无法从 c# windows ZAC68B62ABFD6A9FE26E8AC4236CCE8 应用程序中捕获 Microsoft Edge url - I am not able to capture Microsoft edge url from c# windows forms application 我想将带有 C# windows forms 项目的文件上传到网络服务器 - I want to upload files with a C# windows forms project to a webserver 如何在 C# Windows 窗体应用程序中修复窗体大小而不让用户更改其大小? - How can I fix the form size in a C# Windows Forms application and not to let user change its size? 如何安排 C# Windows 服务在每个月的特定日期执行任务? - How might I schedule a C# Windows Service to perform a task on particular date of every month? 我如何安排 C# Windows 服务每天执行任务? - How might I schedule a C# Windows Service to perform a task daily? 用c#(实际上是服务器)编写Windows窗体应用程序,我想显示诸如“服务器监听”,“已连接”等消息, - Writing a windows forms application in c#, which is actually a server, I want to display messages such as “Server Listening”, “Connected” etc, 我有一个C#Windows窗体应用程序。我可以在网上部署它,以便用户可以通过网络访问吗? - I have a C# Windows Forms application. Can I deploy it on web, so that users can access through web? 我想创建一个共享数据库 c# windows 表单应用程序? - I want to create a shared database c# windows form application?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM