Пишу приложение windows form для "общения" ПК и Arduino посредством COM интерфейса. Arduino отправляет строку формата, например "100;2#". Отправленные данные из Arduino ловлю с помощью:
SerPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
void DataReceivedHandler(object sender_handler, SerialDataReceivedEventArgs ex)
{
SerialPort sp = (SerialPort)sender_handler;
string data = sp.ReadExisting();
test(data)
}
Однако заметил, что после каждого обработанного сообщения от Arduino приложение растёт по памяти и никак его не высвобождает. void DataReceivedHandlerpublic находится в Form1().
public Form1()
{
InitializeComponent();
MMDeviceEnumerator DevEmul = new MMDeviceEnumerator();
MMDeviceCollection allAudioDevice = DevEmul.EnumerateAudioEndPoints(EDataFlow.eRender, EDeviceState.DEVICE_STATE_ACTIVE);
MMDeviceCollection allRecordDevice = DevEmul.EnumerateAudioEndPoints(EDataFlow.eCapture, EDeviceState.DEVICE_STATE_ACTIVE);
//Выводим все активные устройства воспроизведения
for (int i = 0; i < allAudioDevice.Count; i++)
{
checkedListBox1.Items.Add(allAudioDevice[i].FriendlyName);
}
//Указываем параметр Checked устройству, которое сейчас по-умолчанию
MMDevice defaultAudioDevice = GetDefaultDevice();
checkedListBox1.SetItemCheckState(checkedListBox1.FindString(defaultAudioDevice.FriendlyName), CheckState.Checked);
//Отслеживаем изменение в COM
SerPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
void DataReceivedHandler(object sender_handler, SerialDataReceivedEventArgs ex)
{
SerialPort sp = (SerialPort)sender_handler;
string data = sp.ReadExisting();
test(data);
}
void test(string indata)
{
this.Invoke((MethodInvoker)delegate
{
if (indata == "GetVolume")
{
MMDeviceCollection GetVolumeDevice = DevEmul.EnumerateAudioEndPoints(EDataFlow.eRender, EDeviceState.DEVICE_STATE_ACTIVE);
string SendStr = "";
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if (checkedListBox1.GetItemChecked(i))
{
SendStr += checkedListBox1.Items[i].ToString() + ";" + i + "^" + GetVolumeDevice[i].AudioEndpointVolume.MasterVolumeLevelScalar * 100 + "#";
if (defaultAudioDevice.FriendlyName == GetVolumeDevice[i].FriendlyName) SendStr += "1$";
else SendStr += "0$";
}
}
SerPort.Write(SendStr);
//MessageBox.Show(SendStr);
}
else
{
String bufferStr = "";
int readVolume = 0;
int readID = 0;
for (int i = 0; i < indata.Length; i++)
{
if (indata[i] != ';' && indata[i] != '#')
{
bufferStr += indata[i];
}
else
{
if (indata[i] == ';') readVolume = Int32.Parse(bufferStr);
if (indata[i] == '#')
{
readID = Int32.Parse(bufferStr);
textBox1.Text = readVolume.ToString();
progressBar1.Value = readVolume;
allAudioDevice[readID].AudioEndpointVolume.MasterVolumeLevelScalar = (float)readVolume / 100;
}
bufferStr = "";
}
}
}
});
}
}
Пробовал не вызывать функцию test(data), а заменить её на MessageBox.Show(data), но это никак не повлияло на ситуацию. Подскажите, в чём может быть проблема, что я делаю не так?
SerialPort использует потоки threadpool для вызова обработчика событий DataReceived это может приводить к большому пулу потоков если функция обработки не успевает за портом. Диагностика этого возможна из меню Debug -> Windows -> Threads. Так-же обратите внимание на количество событий ErrorReceived.
Для борьбы с этим используйте свойство Handshake для настройки управления потоком, или можно отказаться от использования эвента DataReceived и получать все в ручную:
while (SerPort.IsOpen)
{
uint c = SerPort.ReadByte();
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть dll написаная на с++Необходмо испльзовать ее в с#
Конфиг: Windows Server 2016, x64, 1Гб ОЗУ Создал службу по мануалу Размещение ASPNET Core в службе Windows установил на дом
Есть кусок кода,написанный в python, с помощью api йобита выводит цену по определенной паре
В личном кабинете пользователь может создать список своих делРеализация может показаться вам глупой, но мне интересно ваше мнение по поводу...