Создана простая оконная форма для приема и обработки данных из последовательного порта
также регистрация данных в текстовом файле и отображение в поле расширенного текста.
По какой-то причине он переходит в состояние отсутствия ответа и не может выполнять действия пользователя и зависать.
Насколько я понимаю, в предыдущем коде использовались два потока: один пользовательский интерфейс, а другой - событие получения данных. Это правильно
Но теперь, когда я использую фоновый рабочий, он должен создать другой поток для обработки и добавления в поле log и richtext. Это правильно?
Это мой первый проект на c #, так что извините, если на него уже ответили где-то еще, так как я не могу соотнести эту ситуацию с данными ответами и не могу их реализовать.
Это хорошая идея для фонового работника, если нет, то как я могу решить эту проблему.
Заранее спасибо.
Ранее все приложение работало в потоке пользовательского интерфейса. Теперь я попытался использовать фон для создания нового потока для хранения данных, получаемых из последовательного порта и обрабатывающих внутри этого потока
//earlier code
void DataReceived_Event(object sender, SerialDataReceivedEventArgs e)
{
if (Port.IsOpen)
{
int bytes = Port.BytesToRead;
byte[] buffer = new byte[bytes];
Port.Read(buffer, 0, bytes);
receivedBytes.AddRange(buffer);
ProcessRecievedBytes(null);
}
}
//latest code with background worker
void DataReceived_Event(object sender, SerialDataReceivedEventArgs e)
{
if (Port.IsOpen)
{
int bytes = Port.BytesToRead;
byte[] buffer = new byte[bytes];
Port.Read(buffer, 0, bytes);
receivingBytes.AddRange(buffer);
if (!essentialBgWorker.IsBusy)
{
receivedBytes.AddRange(receivingBytes);
receivingBytes.Clear();
essentialBgWorker.RunWorkerAsync();
}
}
}
private void essentialBgWorker_DoWork(object sender, DoWorkEventArgs e)
{
foreach (byte hexByte in receivedBytes)
{
//color = Color.Gray;
if ((Config.Data.Serial_DisplayLevel == GLOBAL.HEX_LEVEL_NONE))
{
if ((hexByte == '\n') || ((hexByte >= 0x20) && (hexByte <= 0x7E)))
{
String tmpString = new String((char)hexByte, 1);
//essentialBgWorker.ReportProgress(0, tmpString);
//in here i am putting in the log file and appending in the richtext box
PreprocessAppend(tmpString, Color.Black, false);
}
}
}
process.ProcessData(receivedBytes);//in here i am processing the data
receivedBytes.Clear();
}
private void essentialBgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
string str = e.UserState.ToString();
logWriter.Write(str);
logWriter.Flush();
if (e.ProgressPercentage == 0)
{
AppendSerial(str, Color.Black, false);
}
else if (e.ProgressPercentage == 1)
{
AppendSerial(str, Color.Black, false);
}
}
SerialTab.SerialPort.AppendSerial += delegate (string data, Color txtColor, bool newLineCheck)
{
this.BeginInvoke((MethodInvoker)(delegate ()
{
if (newLineCheck && (serialTextBox.Text != "") && (serialTextBox.Text[serialTextBox.TextLength - 1] != '\r') && (serialTextBox.Text[serialTextBox.TextLength - 1] != '\n'))
{
data = "\n" + data;
}
AppendTextbox(serialTextBox, data, txtColor);
}));
};
void AppendTextbox(RichTextBox tb, string data, Color txtColor)
{
if (data == null)
{
return;
}
int start = tb.TextLength;
tb.AppendText(data);
int end = tb.TextLength;
// Textbox may transform chars, so (end-start) != text.Length
tb.Select(start, end - start);
tb.SelectionColor = txtColor;
//reset color to defaults
tb.SelectionLength = 0;
tb.SelectionColor = serialTextBox.ForeColor;
//move caret to bottom of page
ScrollToBottom(tb);
//ensure text buffer stays below 15000 characters
checkTextBoxLength(tb);
}
void checkTextBoxLength(RichTextBox box)
{
//ensure text buffer in text box gets too large
if (box.Text.Length > 15000)
{
box.ReadOnly = false;
box.SelectionStart = 0;
box.SelectionLength = box.TextLength - 10000;
box.SelectedText = "";
box.ReadOnly = true;
}
}