Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программа жрёт память и процессорное время 
V
    Опции темы
Freak_FB
Дата 11.2.2010, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ктулхувед
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 13.10.2006

Репутация: 1
Всего: 4



Помогите найти, где программа начинает жрать память и процессорное время.
Я написал Windows Service, который опрашивает через Serial Port одно устройство, и пишет данные с него в лог.

Serial Port этот виртуальный, то есть эмулируется драйвером устройства типа Serial Port over Ethernet. В следствие багов этого драйвера порт иногда исчезал. Из-за этого моя программа регулярно сыпалась на моментах ввода/вывода на порту.

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

Вот такой код:

Код

private void tstRequest_TrueSecTimerTick()
        {
            try
            {
                switch (counter)
                {
                    case 0:
                        port.Write("!98 99 42  2  5C*");
                        break;
                    case 1:
                        port.Write("!98 99 26 91  2  E8*");
                        break;
                    case 2:
                        port.Write("!98 99 26 76  2  EB*");
                        break;
                    default:
                        break;
                }
                counter++;
                if (counter == 3)
                    counter = 0;

                BrokenPort = false;

                DateTime dt = DateTime.Now;

                NoData = (dt - lastDataReceived > new TimeSpan(0, 0, 5));

                if (NoData)
                {
                    SetNullForData();
                }
            }
            catch (Exception ex)
            {
                BrokenPort = true;

                SetNullForData();

                // Пытаемся оправиться после сбоя

                try
                {
                    port = new SerialPort();
                    SetSerialPortProperties();
                    port.DataReceived += port_DataReceived;
                    port.Open();
                }
                catch
                {
                    // Не получилось...
                }
            }

            UpdateServiceInfo();
        }



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

Как показывает практика: как только я специально удаляю этот порт, служба начинает хавать под 100% процессорного времени и неистово начинает потреблять память.

Кто может подсказать, где ошибка?

Если по некоторым методам есть вопросы, спрашивайте.


--------------------
user posted image
user posted image
Тонет Ктулху, все медведы горят в огне.
Я Креведко, очень страшно сегодня мне.

PM MAIL ICQ Skype GTalk Jabber   Вверх
uranpro
Дата 11.2.2010, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 571
Регистрация: 7.5.2008
Где: Moscow city

Репутация: 1
Всего: 1



для начала сделай так
Код

                try
                {
                    port.DataReceived -= port_DataReceived;
                    //port.Close();//посмотри, нужно ли это перед Dispose(). я точно не знаю =) Возможно будет исключение, если порт закрыт
                    port.Dispose();
                    port = new SerialPort();
                    SetSerialPortProperties();
                    port.DataReceived += port_DataReceived;
                    port.Open();
                }
                catch
                {
                    // Не получилось...
                }

Примечание. 
Всегда вызывайте метод Dispose перед освобождением последней ссылки на объект Component. В противном случае используемые им ресурсы не будут освобождены до тех пор, пока сборщик мусора не вызовет относящийся к объекту Component метод Finalize.
 
ps: если класс имеет интерфейс IDisposeble, то желательно(или необходимо) использовать Dispose.

Это сообщение отредактировал(а) uranpro - 11.2.2010, 16:45


--------------------
I want a perfect soul
PM MAIL ICQ   Вверх
KelTron
Дата 11.2.2010, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(Freak_FB @  11.2.2010,  15:00 Найти цитируемый пост)
служба начинает хавать под 100% 

Ну скорее всего там постоянно валятся исключения на этом месте:
Код

port.Open();

Старый порт не закрыт, поэтому нельзя его открыть ещё раз.
Пройдись отладчиком и узнаешь точно.

Как решить проблему uranpro уже написал. 


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
uranpro
Дата 11.2.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 571
Регистрация: 7.5.2008
Где: Moscow city

Репутация: 1
Всего: 1



msdn> На практике рекомендуется после вызова метода Close подождать некоторое время, прежде чем вызывать метод Open, поскольку порт не всегда закрывается мгновенно.
=)


--------------------
I want a perfect soul
PM MAIL ICQ   Вверх
Freak_FB
Дата 11.2.2010, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ктулхувед
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 13.10.2006

Репутация: 1
Всего: 4



 smile 
Поймите же меня правильно: поскольку порт уже исчез из системы, любые обращения к его свойствам и методам тупо ведут к исключениям. Что и вынуждает меня юзать такой радикальный метод, как забыть о старом объекте и создать новый.

Естественно, Close порождает эксепшен, Dispose порождает эксепшен, да что угодно порождает эксепшен, если объект исчез таким нехорошим образом.

Насчет освобождения ивентов - завтра попробую, но что-то мне кажется, что это не решит проблему.



--------------------
user posted image
user posted image
Тонет Ктулху, все медведы горят в огне.
Я Креведко, очень страшно сегодня мне.

PM MAIL ICQ Skype GTalk Jabber   Вверх
jonie
Дата 12.2.2010, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



Freak_FB, вызывай Dispose в блоке finally, внутри которого будет try{b.dispose();}catch(){/* eat all errors*/} ....


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Freak_FB
Дата 15.2.2010, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ктулхувед
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 13.10.2006

Репутация: 1
Всего: 4



Активный гуглинг показал, что проблема в интернетах встречалась и ранее, и то, что в данной ситуации начинает активно увеличиваться занимаемая память и время работы ЦП, - вполне закономерно, исходя из способа работы класса SerialPort.

Если кому интересно: обсуждение данной проблемы на микрософтовском форуме.

Проблему решил аварийной остановкой службы. И автовосстановление в настройках службы.



--------------------
user posted image
user posted image
Тонет Ктулху, все медведы горят в огне.
Я Креведко, очень страшно сегодня мне.

PM MAIL ICQ Skype GTalk Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0504 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.