Это может быть глупый вопрос, потому что я новичок в С#, но я пытаюсь отправить сигнал с использованием последовательного порта в одном режиме отправки и непрерывного режима. У меня есть флажок, указывающий режим отправки. Когда я нажимаю на флажок и нажимаю 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);
}
Есть ли способ, чтобы я мог снять флажок, когда он находится в бесконечном цикле, чтобы восстановить управление и прекратить отправку? Или есть лучший способ, которым я могу это сделать?
Одним из решений является использование 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)
Поместите вызов DoEvents
внутри вашего в while
цикла:
mySerialPort.Write(bytesToSend, 0, bytesToSend.Length);
Application.DoEvents();
}
cbContinous
флажокcbContinous
в коде? если нет, то ваш цикл infinte - это просто цикл while ...