简体   繁体   中英

Loop-While within a setup timeout that doesn't affect the other functions

I want to put a function on an endless loop but with a timeout countdown. After each time it perform its function, it should stop for a manually-configured amount of time. If I use Sleep, it freezes everything else. Is there a way that I can do this without affecting the other functions in my project?

    private void btn30_Click(object sender, EventArgs e)
    {
        int hour = DateTime.Now.Hour;
        int minute = DateTime.Now.Minute;
        int second;

        do
        {
            if (5 + DateTime.Now.Second > 60)
            {

                second = (DateTime.Now.Second + 5) - 60;
            }
            else if (5 + DateTime.Now.Second == 60)
            {
                second = 0;
            }
            else
            {
                second = DateTime.Now.Second + 5;
            }
            if (sc.checkScheduleStarted() == false)
            {

                sc.Start30(hour, minute, second);
                btn30.Text = "5 second waiting";
                System.Threading.Thread.Sleep(5000);

            }
            else
            {
                sc.Stop();
                btn30.Text = "Countdown - 5";

            }
        } while (loopCycle == true);   
    }

You're using Task.Sleep() on the main UI thread. Obviously you'll end up freezing the UI. You should consider running your calculations in background with Task.Run and then make delays with non-blocking thread Task.Delay :

private void btn30_Click(object sender, EventArgs e)
{
    Task.Run(async() => 
    {
        do
        {
            // Your stuff here...

            // Pick one of the two examples below for your case:

            // 1. Updates the UI of a WPF application
            Application.Current.Dispatcher.Invoke(() => 
            {
                // Update the UI here...
            });

            // 2. Updates the UI of a WinForm application
            Invoke(new Action(() => 
            {
                // Update the UI here...
            }));

            // Make a delay...
            await Task.Delay(5000);
        } while (true);
    });
}

Note that when you want to update the UI from a background thread you have to somehow execute your code that changes the UI in the main thread (the one that created controls you're updating).

I would recommend:

For WPF - Dispatcher.Invoke

For WinForms - Control.Invoke

Make your click handler asynchronous, and use Task.Delay instead of Thread.Sleep() . This will allow the handler to release control to the calling context and allow it to schedule other tasks while waiting for the Delay to pass.

private async Task btn30_Click(object sender, EventArgs e)
{
    int hour = DateTime.Now.Hour;
    int minute = DateTime.Now.Minute;
    int second;

    do
    {
        if (5 + DateTime.Now.Second > 60)
        {

            second = (DateTime.Now.Second + 5) - 60;
        }
        else if (5 + DateTime.Now.Second == 60)
        {
            second = 0;
        }
        else
        {
            second = DateTime.Now.Second + 5;
        }
        if (sc.checkScheduleStarted() == false)
        {

            sc.Start30(hour, minute, second);
            btn30.Text = "5 second waiting";
            await Task.Delay(5000);
//Rest of code

Don't bother with threading. Just drop a Timer control on the form and subscribe to the tick event. The control will call the event within the UI thread and won't freeze the ui.

public class YourForm {    

    private int Seconds = 5;

    private void btn30_Click(object sender, EventArgs e) {
        YourTimer.Start();
    }

    public void YourTimer_Tick(object sender, EventArgs e)
    {
        Seconds--;

        if (Seconds<= 0) {
            YourTimer.Stop();

            // Do your stuff
        }
    }
}

Reference : Timer class

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM