Не освобождается память приложения С#

174
19 марта 2019, 04:50

Пишу приложение 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), но это никак не повлияло на ситуацию. Подскажите, в чём может быть проблема, что я делаю не так?

Answer 1

SerialPort использует потоки threadpool для вызова обработчика событий DataReceived это может приводить к большому пулу потоков если функция обработки не успевает за портом. Диагностика этого возможна из меню Debug -> Windows -> Threads. Так-же обратите внимание на количество событий ErrorReceived.

Для борьбы с этим используйте свойство Handshake для настройки управления потоком, или можно отказаться от использования эвента DataReceived и получать все в ручную:

while (SerPort.IsOpen)
{
    uint c = SerPort.ReadByte();
READ ALSO
Как использовать структуры c++ из dll-ки в с#

Как использовать структуры c++ из dll-ки в с#

Есть dll написаная на с++Необходмо испльзовать ее в с#

291
Не запускается служба на сервера

Не запускается служба на сервера

Конфиг: Windows Server 2016, x64, 1Гб ОЗУ Создал службу по мануалу Размещение ASPNET Core в службе Windows установил на дом

137
Переписать кусок кода на другой язык

Переписать кусок кода на другой язык

Есть кусок кода,написанный в python, с помощью api йобита выводит цену по определенной паре

130
Реализация ToDo Списка на php

Реализация ToDo Списка на php

В личном кабинете пользователь может создать список своих делРеализация может показаться вам глупой, но мне интересно ваше мнение по поводу...

129