Приложение winforms , есть довольно большой код который выполняется в новых потоках .
В коде много функций , там и работа с сетью и использование сторонних библиотек , вообщем кода много и за всем не уследить .
Софт работает нормально 1-2 дня , ест под 80% цп но стабильно . Однако через это время начинает работать со скоростью улитки (будто большая часть потоков умерла) .
Пробовал во время таково вод застоя смотреть thread.IsAlive но вроде как все потоки живы .
Можно ли как-то узнать какой именно код в данный момент выполняют потоки ? Чтоб найти место где они стопорятся .
Константин Теплоухов, я когда делал многопоточные приложения, непосредственно перед запуском потока записывал его id в потокобезопасный список, а при завершении потока (в процедуре потока) - удалял id из списка. В итоге я всегда имел актуальный список имеющихся потоков, который можно было вывести в ListView и увидеть: что за поток, что делает, время его запуска, некотрые параметры и т.д.
Отладчик в студии и в райдере позволяют поставить на паузу всё приложение даже без точек останова.
Когда приложение на паузе - ты можешь посмотреть список всех живых управляемых потоков и посмотреть, на каком участке кода они находятся.
Но если не получится это применить (например на целевой машине не стоит студия/райдер) или это просто слишком неуловимая ошибка, то Тогда остаётся только обмазаться телеметрией (логами, метриками) и смотреть, что происходит.
Студия не стоит , так как сервер не мой и особого доступа нету . На личном пк где пишу не получается поймать так как банально пк слабоват для софта + не могу же я свой пк на 2 дня в афк поставить ...
Но планирую арендовать дедик и попробовать там поставить студию . Только можете подсказать как
ты можешь посмотреть список всех живых управляемых потоков и посмотреть, на каком участке кода они находятся.
что-то я такого функционала не нашёл .
ps: у меня студия 2022
Василий Банников, ещё небольшой вопрос , не думаю что ради него стоит создавать тему . Является ли обычная конструкция потокобезопасной и может ли она быть причиной проблем ?
Константин Теплоухов, в каком смысле "потокобезопасная"?
Вообще, если ты из двух разных потоков попытаешься сделать ++ одновременно - вполне возможна такая ситуация, что он заинкрементится только 1 раз.
По тому тебе следует использовать для этой цели Interlocked.Increment
А расход памяти смотрели? Похоже на утечки памяти и уход системы в глубокий свап. Что показывает менеджер задач? Нормальный - типа ProcessExplorer, а не встроенный. Еще могут быть зависшие потоки, которые чего-то там ждут - например, потерянного ответа на сетевой запрос. Надеюсь, все сетевые запросы идут с таймаутом? А еще могут быть какие-то косяки в используемых либах. Как тут уже сказали - добавляйте логирование как минимум в ключевых местах, а как максимум - везде и всюду и потом уже разбирайте логи и ищите где именно проблема.
С памятью всё хорошо (опять же если верить встроенному диспетчеру)
Сетевые запросы с таймаутом . Логирование не помогает . Делал запись Exception в функциях в файл , по итогу понял что ошибки только с сетевыми запросами . Но они есть всегда , и в начале работы софта . Просто через 1-2 дня у софта будто падает скорость до 1/100 .
Смотрите через ProcessExplorer - во встроенном диспетчере инфы никакой. В PE есть даже вкладка с потоками. Дисковая подсистема? Может там где-то открыто миилон хэндлеров файлов или еще чего. А в какой именно части приложения скорость падает? Вычисления? Графика? Сеть? Диск?
VoidVolker, вот тут и проблема , даже не могу понять где именно . Логика работы каждого потока примерно такая
1- генерирует значение (цифры / буквы)
2- отправляет результат get запросом , ждёт ответа
3- если ответ нужный обрабатывает его сторонней библиотекой
4- записывает результат в нужный файл
это если прям ну очень коротко и обобщённо .
Как и сказал , пробовал записывать Exception но ничего толкового не дало . Если первый день / два работает хорошо , быстро то потом скорость падает до 1/100 ...
В таком случае добавляйте более детальное логирование по каждому этапу и смотрите где именно возникает проблема и сужайте область поиска до конкретного места. Теоретически - самое медленное место в записи файла, потом сеть. Возможно, имеет смысл сделать очередь и пул воркеров и каждый шаг передавать из очереди в пул для процессинга, а уже за этим пулом следить более детально.
Константин Теплоухов, возможно у Вас превышается лимит соединений с сервером?
Этот параметр прописывается в App.config проекта.
По-умолчанию возможно установить только четыре параллельных соединения с сервером.
Из относительно простых способов - APM (NewRelic APM или другой).
ИМХО, в большинстве случаев позволяет понять в чем проблема не залезая слишком глубоко.