finsight / QUIKSharp

QUIK# (QUIK Sharp) is the QUIK Lua interface ported to .NET.
Other
230 stars 134 forks source link

Fix memory leak. Dispose in recreating instances. #311

Closed chislovMax closed 2 years ago

chislovMax commented 2 years ago

Решение этого ишью

Самый важный исправленный момент, который побудил исправления, это лик во время отключения соединения квика к серверу, когда был уже подключен Quki# к нему. И если после этого попробовать запустить Quki# снова - уходил в бесконечный цикл внутри таски _callbackInvokerTask:

Результат PR: Создан зависимый CancellationTokenSource, если отменится _cts, то и отменит этот же, операция завершится, этот зависимый токен уничтожается сразу после обработки асинхронной операции чтения, если возникает такой цикл CallbackNode и всё, что к нему было приложено так же зачищается.

Все остальные правки с вызовами Dispose были намерено сделаны не в момент отмены, а в основном при пересозданиях (ничего не ломает, но работает лучше)

Pr0phet1c commented 2 years ago

Изменения действительно важные и нужные. Спасибо. Хотя, описанного потребления памяти никогда не наблюдал у себя (обычно работает одновременно 3-4 программных комплекса, подключенных к двум терминалам от разных брокеров), и редко когда потребление памяти одним приложением превышает 100Мб. Код просмотрел бегло, и вроде бы ничего критичного не увидел. Так что надеюсь, Вы протестировали изменения в реальной работе. Сейчас перенесу изменения к себе и сам понаблюдаю что изменилось по сравнению с текущим положением дел.

buybackoff commented 2 years ago

@chislovMax Спасибо! Тому коду 6-7 лет, когда я бегло посмотрел на использование CTS после issue, подумал - кто же так замудренно написал!? 😄

Я добавил System.Threading.Channel не так давно, почти не думая, чтобы решить проблему reordering-а сообщений. Я так понимаю, утечка в первую очередь из-за каналов? До этого Таски просто отправлялись в пул потоков.

chislovMax commented 2 years ago

Да, всё верно. В первую очередь это из-за того, что либа каналов цепляла каждый раз событие к переданному _cts. И завершала асинхронную операцию не по этому _cts.