Чекбокс бесконечного цикла c #

1

Это может быть глупый вопрос, потому что я новичок в С#, но я пытаюсь отправить сигнал с использованием последовательного порта в одном режиме отправки и непрерывного режима. У меня есть флажок, указывающий режим отправки. Когда я нажимаю на флажок и нажимаю send, приложение застревает в бесконечном цикле, и я теряю контроль над приложением.

    private void bSend_Click(object sender, EventArgs e)
    {
        byte[] Break = new byte[1] { 0x00 };
        string input = tbTX.Text;
        byte[] bytesToSend = input.Split().Select(s => Convert.ToByte(s, 16)).ToArray();
        while (cbContinuous.Checked) // Checkbox named continuous
            {
                // Generate Break and MAB signal
                headerSignal();

                // Set back to DMX timing
                DMXSettings();
                mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

            }
        // Generate Break and MAB signal
        headerSignal();

        // Set back to DMX timing
        DMXSettings();
        mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

    }

Есть ли способ, чтобы я мог снять флажок, когда он находится в бесконечном цикле, чтобы восстановить управление и прекратить отправку? Или есть лучший способ, которым я могу это сделать?

  • 2
    Пусть ваша основная логика будет в другой теме. Не выполняйте долгих операций в потоке пользовательского интерфейса. Посмотрите на BackgroundWorkers или async / await.
  • 3
    Вы когда-нибудь cbContinous флажок cbContinous в коде? если нет, то ваш цикл infinte - это просто цикл while ...
Показать ещё 2 комментария
Теги:
serial-port

2 ответа

2

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

    private readonly List<Task> taskList = new List<Task>();

    private void bSend_Click(object sender, EventArgs e)
    {
        var task = Task.Run(() =>
        {
            byte[] Break = new byte[1] {0x00};
            string input = tbTX.Text;
            byte[] bytesToSend = input.Split().Select(s => Convert.ToByte(s, 16)).ToArray();
            while (cbContinuous.Checked) // Checkbox named continuous
            {
                // Generate Break and MAB signal
                headerSignal();

                // Set back to DMX timing
                DMXSettings();
                mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

            }
            // Generate Break and MAB signal
            headerSignal();

            // Set back to DMX timing
            DMXSettings();
            mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);
        });

        taskList.Add(task);
    }

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

Вы можете прочитать этот вопрос о переполнении стека перед использованием Application.DoEvents:

Использование Application.DoEvents

Вы также можете учесть, что.NET 4.5 поддерживает асинхронное программирование с помощью ключевых слов ожидания и async:

Асинхронное программирование с использованием Async и Await (С# и Visual Basic)

0

Поместите вызов DoEvents внутри вашего в while цикла:

   mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);

   Application.DoEvents();
}
  • 1
    Это поможет справиться с проблемой, но лучше подумать о том, как это работает.
  • 0
    Спасибо, я думаю, что это будет работать на данный момент.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню