L oop - в течение времени ожидания установки, которое не влияет на другие функции - PullRequest
0 голосов
/ 11 января 2020

Я хочу поставить функцию на бесконечное l oop, но с таймаутом. После того, как каждый раз он выполняет свою функцию, он должен останавливаться на время, настроенное вручную. Если я использую Sleep, он замораживает все остальное. Есть ли способ, которым я могу сделать это, не затрагивая другие функции в моем проекте?

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

Ответы [ 3 ]

1 голос
/ 11 января 2020

Вы используете Task.Sleep () в основном потоке пользовательского интерфейса. Очевидно, вы в конечном итоге заморозить пользовательский интерфейс. Вам следует рассмотреть возможность выполнения ваших расчетов в фоновом режиме с помощью Task.Run, а затем выполнить задержки с неблокирующим потоком 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);
    });
}

Обратите внимание, что когда вы хотите обновить пользовательский интерфейс из фонового потока, вы должны каким-то образом выполнить свой код, который изменяет пользовательский интерфейс в основном потоке (тот, который создал элементы управления, которые вы обновляете).

Я бы порекомендовал:

Для WPF - Dispatcher.Invoke

Для WinForms - Control.Invoke

0 голосов
/ 13 января 2020

Не заморачивайся с резьбой. Просто перетащите элемент управления Timer на форму и подпишитесь на событие галочки. Элемент управления вызовет событие в потоке пользовательского интерфейса и не заблокирует пользовательский интерфейс.

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
        }
    }
}

Ссылка: Класс таймера

0 голосов
/ 12 января 2020

Сделайте ваш обработчик кликов асинхронным и используйте Task.Delay вместо Thread.Sleep(). Это позволит обработчику освободить управление для вызывающего контекста и позволить ему планировать другие задачи в ожидании прохождения Delay.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...